wait() 시스템 콜의 동작 과정

Ehigh·2024년 10월 9일

배경

Lock에 대한 내용을 공부하며, '대기하는 과정은 CPU에 부하를 주지 않을까?' 라는 궁금증이 있어, 이를 조사했다.

이런 생각을 한 이유는, 특정 조건을 만족할 때까지 대기하는 과정이 '일정 주기마다 해당 조건이 만족하는지를 계속 체크하는 과정' 일 것이라 생각했고(while문처럼), 따라서 많은 연산을 발생시키는 것이 아닐까 생각했기 때문이다.

이 현상을 Busy Waiting이라고 부른다고 한다.

이런 궁금증을 해결하기 위해 일단 wait() 시스템 콜의 동작 과정에 대해 조사했다.
Lock을 사용할 때 대기하는 것은 꼭 프로세스의 종료 뿐만이 아닌 특정 조건이 만족하는지를 체크하는 것이기에, wait() 외의 부분에서 어떻게 동작하는지에 대한 조사는 추가적으로 필요하다.

wait()의 동작 과정

  1. 부모 프로세스에서 fork()해서 자식 프로세스를 생성한다. 자식 프로세스의 PCB에 부모 프로세스의 PID를 저장한다.
  2. 부모 프로세스의 실행(=CPU 점유)를 중단하고, 대기 큐로 보낸다.
  3. 자식 프로세스의 실행이 종료되면, 자식 프로세스 PCB에 종료 상태(정상 종료인지, 에러 발생인지 등)를 기록한다.
    3-1. 이 때 종료된 자식 프로세스는, 부모 프로세스가 정보를 가져갈 때까지 남아있는다.
  4. 자식 프로세스 PCB에 저장된 부모 프로세스의 PID를 가지고, 대기 큐에서 해당 프로세스를 찾아 준비 큐로 옮긴다.
  5. 준비 큐로 옮겨진 부모 프로세스가 스케줄러에 의해 CPU를 할당받으면, 자식 프로세스의 PCB에서 종료 상태 정보를 가져와 wait() 시스템 콜의 반환값으로 반환한다.

좀비 프로세스

프로세스는 종료 후에도, 부모 프로세스에서 종료 상태 정보를 가져가기 전까지 프로세스 테이블에 남아있는다. 이를 좀비 프로세스라고 한다.

결론

wait() 시스템 콜의 동작 방식은 (지속적으로 연산을 발생시키는)모니터링 방식이 아닌 이벤트 기반 방식으로, 우려했던 것처럼 많은 부하를 발생시키지 않는다.
다만 Lock과 관련된 대기 로직은 wait() 호출 외에도 다른 많은 로직을 포함하거나, 혹은 wait() 자체를 포함하지 않을 수 있으므로, 추가적인 조사가 필요하다.

0개의 댓글