Shell
-> kernel과 user을 연결해주는 interface
-> 사용자와의 interaction
-> interaction: user의 입력을 받고 실행 결과를 화면에 출력
Shell에서 problem
-> fork 없이 exeve 호출하면 shell은 새로운 프로그램으로 존재하고 더 이상 존재 x
-> shell은 fg의 종료를 기다리고 reap
-> bg가 종료되면 zombie가 됨
-> shell은 zombie를 수거하지 않음
-> memory leak발생
Solution
-> ecf
-> bg 완료되면 정규 처리 중단, process 알림 (signal) 보냄
Signal
-> system에서 event 발생했음을 알리는 message
-> Signal => Stop => Reap => continue
-> kernel이 process로 signal 보냄
-> ID 로 신호 식별
-> signal에는 ID와 도착 여부
Signal을 보내는 이유
1. System event 감지
-> ex) 0으로 나누기, 자식 process 종료
2. 다른 process가 kill system call 호출 -> 자식 process 종료
Signal에 대한 반응
1. Ignore
2. Terminate
3. Signal handler 실행
Signal 특징
-> 비동기적 처리
-> 동일 signal 중첩 X
-> signal을 차단할 수 있음
-> pending signal은 최대 한 번 수신
Pending Signal
-> 대기 중인 신호 집합을 나타냄
Blocked Signal
-> 차단된 신호 집합을 나타냄
-> sigprocmask()를 사용
Process Group
-> shell에서 child와 grouoppid를 분리하지 않으면 Ctrl + c 경우 process 뿐만 아니라 shell program도 종료
Ctrl + c
-> SIGINT (각 프로세스 종료)
-> fg group 모든 작업에 보냄
Ctrl + z
-> SIGSTP (각 프로세스 중단)
-> fg group 모든 작업에 보냄
-> bg로 이동
Handler에서 signal처리
-> pnb = pending & ~blocked 계산
-> pnd는 대기 중이며 차단되지 않은 신호 집합
-> pnb = 0이면 새로운 process의 다음 명령어로 제어 전달
-> pnb != 0 이면 signal 강제 수신, 모든 pnb 비트가 처리될 때까지 반복
Signal의 동작
1. process terminate
2. process stop
3. signal ignore
Signal Handler
-> handler_t * signal (int signum, handler_t * handler)
-> SIG_IGN: 신호 무시
-> SIG_DFL: 기본 동작으로 되돌림
Signal handler concurrent flow
-> main함수와 handler은 동시에 실행
-> 둘은 동일한 process
Nested Signal Handler
-> 동일한 프로세스에서 N개의 동시 흐름이 발생 가능
-> 예상치 못한 결과 초래할 수 있음
Implicit blocking mechanism
-> 동일한 signal은 blocking
Explicit blocking mechanism
-> sigprocmask() 함수 사용 하여 신호를 block / unblock
-> 서로 다른 sig들을 ordering
Shared data Problem
-> handler와 main은 동일한 global data 구조 공유
1. handler는 단순하게 유지
2. async-signal-safe가 보장된 함수만 호출
3. handler 진입/종료 시 errno 저장/ 복원
4. shared data 접근할 때 모든 sig 일시적 차단
Async-signal-safe 함수
-> reentrant (재진입 가능, stack에 모든 변수 저장, local 변수 사용) 하거나
-> non-interruptible (신호 차단하여 실행 방해 방지) 해야함
Sio 함수
-> sio_puts: 문자열 출력
-> sio_putl: 정수 출력
-> sio_error: error 메세지 출력 후 종료
** Pending Signal은 각 유형에 대해 최대 하나의 신호만 가능하여
신호를 event counting (자식 종료 횟수) 에 사용할 수 없음
-> 이를 해결하기 위해 wait 함수 사용
Sigaction 함수
-> 이식성 good
-> main과 handler가 concurrent 하기 때문에 race가 발생할 수 있음
-> addjob과 deletejob은 동기화가 필요
-> fork 전에 block , fork 후에 unblock
Sigchild waiting
-> sigchild를 받을 때까지 wait하는 것은 busy waiting 이므로 cpu 낭비
-> sleep을 써도 응답성 떨어짐
-> sigsuspend(const sigset_t *mask) 사용
-> 이전 bit vector과 sig_child 전달시 wakeup
'시스템프로그래밍' 카테고리의 다른 글
| 시스템프로그래밍(14) - vm (0) | 2024.12.14 |
|---|---|
| 시스템프로그래밍(13) - io (0) | 2024.12.14 |
| 시스템프로그래밍(11) - ecf-procs (0) | 2024.12.14 |
| 시스템 프로그래밍(10) - Linking (1) | 2024.12.14 |