[인프런 워밍업클럽 2기] CS전공지식_Mission01
운영체제while(true){ wait(1); // 1초 멈춤 bool isActivated = checkSkillActivated(); // 체크 }위 코드는 1초 마다 플레이어가 스킬을 사용했는지 체크하는 코드입니다. 이 방식은 폴링방식입니다.1초마다 체크하기 때문에 성능에 좋지 않습니다. 이를 해결하기 위한 방식으로 어떤 걸 이용해야 할까요? 이런 풀링 방식의 경우 계속 매초마다 확인을 하니까 효율이 좋지 못하다.이전에 서버에게 클라이언트에서 로그인 인증 됬는지 처리하기 위해 계속 해서 switch 문에 들락날락 처리 되도록 한적이 있는데. 확실히 삑나간적이 있었다.이럴때 필요한게 인터럽트 인데 일종의 대기상태 라고 생각하면 될 것 같다.CPU는 다른 작업을 실행시키거나 하여 잠시 대기시키고 해당 작업이 완료되는 시점에 신호를 받아 완료 시킨다. 언리얼엔진에서도 비슷하게 조건을 주어 매초마다 주는 Tick 발생을 제어하는 것들이 있는데.상태머신에서도 볼 수 있는 현상이다.조건을 주어 다른 것이 실행되게 하고 입력값이 들어오면 그때서야 실행하는 것이다. 인터럽트도 일정 입력이 들어올 때까지 작동하지 않고 들어오면 인터럽트에 의해 다른 업무를 시키고 그 업무로 들어가게 한다. 해결방법인터럽트 핸들러 : 특정이벤트가 발생했을 때 인터럽트가 발생하도록 처리 CPU는 대기상태에서 벗어나서 해당 이벤트를 즉시 실행상태 플러그 : 인터럽트 핸들러에서 상태 플래그를 설정하고 loop에서 이 플래그를 체크하여 작업을 수행하도록 volatile bool skillActivated = false; void interruptHandler() { skillActivated = true; // 인터럽트 발생시 플래그 } while(1) { if (skillActivated) { skillActivated = false; // 플래그 초기화 } // 다른 작업 수행 }우선 순위 관리를 통해 중요한 이벤트 부터 처리타이머 사용 : 주기적인 작업시 타이머 설정해서 일정 시간마다 인터럽트 처리다용도 입출력(GPIO)핀의 변화를 감지해서 인터럽트 발생등등 2. 프로그램과 프로세스가 어떻게 다른가요?프로그램 명령문의 집합체일종의 실행파일같이 .exe 형태로 이루어짐컴퓨터의 관점에서 저장장치만 사용하는 수동적 존재 프로세스실행중인 프로그램저장장치에서 프로그램이 메모리에 올라간 것메모리도 사용하고 운영체제 CPU 스케줄링에 따라 CPU도 사용됨, 능동적인 존재이다. 3. 멀티프로그래밍과 멀티프로세싱이 어떻게 다른가요?멀티 프로그래밍메모리에 여러개의 프로세스가 올라온 것 멀티 프로세싱CPU가 여러개의 프로세스를 처리하는 것 -> 오늘날 멀티프로세싱 프로그래밍이 전부다 쓰인다.메모리에는 여러개의 프로세스가 올라오는 멀티프로그래밍, 시분할 처리로 CPU가 각각의 프로세스를 짧은 시간동안 교대로 실행하는 멀티프로세싱이 있다. (동시에 실행된다는 개념이 아니다) 4. 운영체제는 프로세스를 관리하기 위해서 어떤 것을 사용하나요?운영체제는 프로세스가 만들어지면 해당 프로세스의 정보를 가지고 있는 PCB를 만든다. 이것은 연결리스트 자료구조 마냥 저장되어있는데. 프로세스가 종료되면 해당 리스트에서 프로세스의 PCB를 제거합니다. 그러면서 연결리스트의 구조는 그대로 유지 합니다. PCB의 구조는포인터프로세스 상태프로세스 ID프로그램 카운터레지스터 정보메모리관련정보CPU스케줄링 정보 등 PCB내부에서 여러개의 동작이 실행되어 운영체제에 의해 관리됩니다. 5. 컨텍스트 스위칭이란 뭔가요? 프로세스를 실행하는 중에 다른 프로세스를 실행하기 위해 실행 중인 프로세스를 저장하고 다른 프로세스의 상태값으로 교체는 작업을 - 컨텍스트 스위칭 이라고 한다. 컨텍스트 스위칭은 PCB의 내용이 변경된다.실행중인 프로세스의 작업내용을 PCB에 저장하고 실행될 기존 프로세스의 PCB의 내용대로 CPU가 다시 셋팅 된다. 컨텍스트 스위칭이 발생시 PCB의 변경 값 프로세스 상태프로그램 카운터 : 다음 실행할 명령어 주소레지스터 값 & 메모리관련 정보 : 각종 레지스터의 값 정보 발생 이유 CPU 점유시간이 다 되거나 입출력 요청이 있거나다른 종류의 인터럽트가 있을 때 발생할 때 자료구조와 알고리즘1. 여러분은 교실의 학생 정보를 저장하고 열람할 수 있는 관리 프로그램을 개발하려고 합니다.이 때 여러분이라면 학생의 정보를 저장하기 위한 자료구조를 어떤 걸 선택하실 건가요? 이유를 함께 적어주세요.학생 정보를 저장하기 위해 구조체와 벡터를 결합해 사용할 수 있을 것 같다. 구조체는 학생 정보를 표현하고, 벡터는 여러 학생 정보를 동적으로 저장할 수 있다. C++에서는 이러한 것이 STL에 컨테이너로 되어 사용가능하다.사용이유구조체 사용 : 학생 정보를 하나의 단위로 묶어 관리하기 위해 구조체를 사용학생의 이름나이학생ID등의 속성을 쉽게 다룰 수 있다. 벡터 사용 : 벡터는 동적 배열로, 학생 수가 변동 될 수 있는 상황에 유용하다. 학생을 추가하거나 삭제할 때 유연하게 대처가능 하다. #include <iostream> #include <iomanip> #include <string> #include <vector> using namespace std; struct Student { // 기본적으로 구조체는 기본적으로 public string name; int age; string studentId; // 구조체 변수 초기화 Student(string n, int a, string id) : name(n), age(a), studentId(id) {} }; class StudentManager { public: void AddStudent(const string& name, int age, const string& studentId) { vStudents.emplace_back(name, age, studentId); // 객체내 인자만받아 함수 내에서 객체 생성해 삽입 - emplace_back 생성자 한번만 호출 } /*width() 또는 iomanip/ setw()로 정리*/ void DisplayStudents() const { for (const auto& student : vStudents) { cout << "| " << "Name: " << student.name << " |" << setw(6) << "Age: " << student.age << " |" << setw(13) << "Student ID: " << student.studentId << " |" << endl; } } private: // 공개가 필요없는 vector<Student> vStudents; }; int main() { StudentManager manager; manager.AddStudent("홍길동", 20, "20230001"); manager.AddStudent("인프런", 21, "20230002"); manager.AddStudent("감자 ", 25, "20230003"); cout << "학생정보: " << endl; manager.DisplayStudents(); return 0; } 2. 여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요.큐(Queue)자료구조를 사용해서 FIFO방식으로 데이터를 처리하므로 주문이 들어온 순서대로 처리할 수 있습니다. STL에 queue를 사용할 수 있습니다.사용이유FIFO : 선입선출 방식, 주문이 들어온 순서대로 처리할 수 있어서 주문관리에 적합합니다. 고객 대기 시간을 최소화할 수 있습니다. (단. 끼어들기 금지)간편한 관리 : C++STL 제공하기에 복잡한 구현없이 간편하게 큐를 관리 확장성 : 새로운 주문 추가또는 기존 주문을 처리하는 과정이 명확해서 확장및 유지보수 용이 /*여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요. */ #include<iostream> #include<queue> #include<string> using namespace std; typedef struct Order { string customerName; // 고객이름 string item; // 주문한 물건 int quantity; // 주문 수량 int price; // 주문 가격 int Sum; // 주문 총 가격 // 각 변수 초기화 Order(string name, string itm, int qty, int pri, int sum) : customerName(name), item(itm), quantity(qty), price(pri), Sum(sum) {} } Orderinfo; class OrderManager { public: void AddOrder(const string& name, const string& item, int quantity, int price, int Sum) { Sum = (price * quantity); orders.emplace(name, item, quantity, price, Sum); // 새로운 주문 객체를 큐에 추가 } void ProcessOrder() // 주문 처리 { // 큐에 주문이 있는가? if (!orders.empty()) { Order currentOrder = orders.front(); // 현재 처리할 주문을 큐의 앞에서 가져온다. orders.pop(); // 주문을 큐에서 제거 // 처리 중인 주문 정보 출력 cout << "Processing order for |"; cout << currentOrder.customerName << ": " << currentOrder.item << ": " << currentOrder.quantity << " | " << currentOrder.price << " | " << currentOrder.Sum << " | " << endl; } else { cout << "No orders to process. " << endl; // 주문이 없을 때 } } // 큐에 주문이 있는지 확인 bool bfHasOrders() const { return !orders.empty(); // 큐가 비어있지 않으면 true반환 } private: // 주문을 저장할 큐 queue<Order> orders; }; int main() { OrderManager manager; // 주문 추가 manager.AddOrder("김감자", "토마토", 2, 3000, NULL); manager.AddOrder("인프런", "바나나", 1, 2000, NULL); while (manager.bfHasOrders()) { manager.ProcessOrder(); // 주문처리 } return 0; }