⭐️ 8.5. Signals
8.4장까지 봐왔던 여러 예외처리흐름 (interrupt, trap, fault, abort)은 하드웨어와 커널 단에서 벌어지는 일이라서 유저 프로세스 입장에서 보여지지 않는다. 하지만 편의성을 위하여, OS는 유저 프로세스들에게 시그널이라는 이름의 메시지 리스트를 제공하여 시스템 이벤트를 발생시킬 수 있게 되었다.
DUMP#
8.5.1. Signal Terminology#
- sending a signal: 커널이, 프로세스가 시그널을 프로세스에게 (심지어 본인에게도) 시그널을 보낼 수 있다.
- receiving a signal: 받는 프로세스는 해당 시그널을 개무시 할 수도 있고, 시그널 핸들러를 따로 두어 처리하게 만들 수도 있다.
- pending signal? process가 block 상태인 경우 시그널이 말소하는 것을 막기위해 도입됨.
8.5.2. Sending Signals#
- process group: 자식 프로세스는 항상 부모 프로세스의 그룹이다. 자식 프로세스는 자기의 그룹을 바꿀 수도 있다.
kill
함수를 사용하여 자기 그룹한테 (pid=0) 또는 자식 프로세스한테 (pid > 0) 시그널을 보낼 수 있다. 함수명이kill
이지만 꼭SIGKILL
만을 보낼 수 있는 건 아님.
8.5.3. Receiving Signals#
- 프로세스가 커널에 의해 깨어났을 때 (context switching에 의해) 제일 먼저 하는 일은 unblocked pending signals을 체크하는 것이다. 없다면 자연스레 다음 명령어를 실행할 것이고, 그렇지 않다면 커널은 pending signals 중에 가장 작은 시그널 k를 뽑아 해당 프로세스에게 먹일 것이다.
- 별다른 시그널 핸들러를 만들지 않았다면 default behaviours가 실행된다.
- installing the handler:
signal(signum, handler)
를 호출하여 함수포인터 handler를 등록할 수 있다.
8.5.4. Blocking and Unblocking Signals#
- implicit blocking과 explicit blocking이 있는데, 이해하지 못하겠음
8.5.5. Writing Signal Handlers#
- 시그널은 OS 단에서 제공해주는 기능이기 때문에 OS가 다르면 시그널도 다르다.
- 핸들러는 메인 프로그램과 동시적으로 돌아가기도 해서 공유자원(전역변수) 관리가 까다로워진다.
- 서로 다른 시그널들끼리 충돌할 수도 있다.
- 해당 절에서는 비동기 안전 함수들에 대해 소개하고
volatile
전역변수를 선언해 사용하는 등 안전하게 시그널 핸들러를 작성하는 방법에 대해 이야기한다.
8.5.6. Synchronizing Flows to Avoid Nasty Concurrency Bugs#
시그널은 동시성 문제를 가지고 있다고 했다. 동시성 흐름을 동기화 하는 자세한 방법은 12장에서 진행이 된다.
8.5.7. Explicitly Waiting for Signals#
해당 챕터를 이해하기 위해선 8.5.4. blocking and unblocking signals에 대한 적절한 이해가 선행되어야 한다.