Signal

June Lee·2021년 4월 15일
0

운영체제

목록 보기
19/25

Signal은 유저 레벨(OS 레벨 X)에서의 인터럽트이다. 시그널은 asynchronous(언제 들어올지 모르는) urgent event를 다룬다.

프로세스는 interrupt가 들어와서 커널 모드로 trap한 후 할 일을 마치고 유저 모드로 돌아가기 직전에 시그널 핸들러로 가서 들어온 시그널이 있는지를 확인한다.
이렇게 동작하는 이유는, 프로세스는 언젠가는 반드시 유저모드로 돌아간다는 사실이 보증되어있기 때문이다.
다시 말하면 돌아가는 프로그램에서 ctrl+c를 눌러서 프로세스를 죽일 때, 유저가 보기에는 이것이 리얼 타임으로 죽는 것처럼 보이지만 사실은 그 사이에 약간의 딜레이가 존재한다.

Pending Signal : 아직 처리되지 않은 시그널
Signal Blocking : 시그널도 인터럽트처럼 막아둘 수 있음
-> 펜딩 시그널이 있다는 것은 아직 유저 모드로 돌아가지 않았다는 뜻이다.


System call과 Signal

유저 레벨에서 시그널은 인터럽트 핸들링과 유사한 기능을 한다고 말했다. 그렇다면, I/O와 같은 System call 작업 중에 시그널이 들어온다면 어떤 일을 먼저 처리해야할까?

  1. I/O가 끝나면 그때 시그널을 처리한다.
    Disk에 관한 시스템 콜, 예를 들어 read()와 같은 명령은 매우 빨리 끝난다는 사실이 보증된다. 또한, 시그널 처리는 어차피 커널 모드에서 유저 모드로 돌아갈 때 해야하기 때문에, I/O가 끝난 뒤 시그널을 처리해줄 수 있다.

  2. I/O를 포기하고 시그널을 먼저 처리한다.
    위에서 말한 read()와 같은 syscall은 빨리 끝나는 것을 보증하지만, 시간이 얼마나 걸릴지 모르는 I/O, 예를 들어 getchar()와 같은 것인 I/O가 끝날 때까지 기다려줄 수가 없다. 이때에는, I/O를 처리하기 위해 블락되어있던 프로세스를 깨워서 ready 상태로 만든 후, 시그널을 먼저 처리한다.
    그리고 I/O 작업의 경우, 다시 시작하거나 Error return을 해준다.(OS에 따라 구체적인 처리 방법은 조금 다르다.)

따라서, 리눅스에서는 블락 상태가 두 개로 나뉘어진다.

1) TASK_UNINTERRUPTABLE
: 시그널에 의해 방해받지 않는 블락 상태
2) TASK_INTERRUPTABLE
: 시그널이 방해할 수 있는 블락 상태

profile
📝 dev wiki

0개의 댓글