๐ง ์๊ทธ๋
์ด๋ฒคํธ๊ฐ ์์คํ ์ ๋ฐ์ํ๋ค๋ ๊ฒ์ ํ๋ก์ธ์ค์๊ฒ ์๋ ค์ฃผ๋ ์งง์ ๋ฉ์ธ์ง
์๊ทธ๋์ ์์์์ค์ ์ํํธ์จ์ด ํํ์ ์์ธ์ ์ธ ์ ์ดํ๋ฆ์ผ๋ก์จ, ์๊ทธ๋์ ํ๋ก์ธ์ค์ ์ปค๋์ด ๋ค๋ฅธ ํ๋ก์ธ์ค๋ฅผ ์ค๋จํ๋๋ก ํฉ๋๋ค.
์๊ทธ๋์ ์์ธ์ํฉ๊ณผ ์ธํฐ๋ฝํธ๋ฅผ ์ปค๋์์ ์ถ์ํํ ๊ฐ๋ ์ผ๋ก์จ, ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ปค๋์ด ํ๋ก์ธ์ค์๊ฒ๋ก ์๊ทธ๋์ ๋ณด๋ด์ฃผ๋ ํํ๋ฅผ ๊ฐ์ง๋๋ค.
์๊ทธ๋์๋ 30๊ฐ์ ์ข ๋ฅ๊ฐ ์์ผ๋ฉฐ, ๊ฐ ์๊ทธ๋์ ์ ์ ์์ด๋๋ก ๊ตฌ๋ถํฉ๋๋ค.(1 - 30)
์๊ทธ๋์ ํฌํจ๋ ์ ๋ณด๋ ์๊ทธ๋์ ์์ด๋์ ์๊ทธ๋์ด ๋์ฐฉํ๋ค๋ ์ฌ์ค์ ๋๋ค.
๋ค์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ๋ช๋ช ์๊ทธ๋๋ค์ ๋๋ค.
์๊ทธ๋์ ๋ชฉ์ ์ง ํ๋ก์ธ์ค๋ก ์ ๋ฌํ๋ ๊ฒ์ ์๊ทธ๋ ์ก์ ๊ณผ ์๊ทธ๋ ์์ ์ ๋ ๋จ๊ณ๋ก ์ด๋ฃจ์ด์ง๋๋ค.
๐ง ์๊ทธ๋ ์ก์
์ปค๋์ ๋ชฉ์ ์ง ํ๋ก์ธ์ค์ ์ปจํ ์คํธ ๋ด์ ์๋ ์ผ๋ถ ์ํ๋ฅผ ๊ฐฑ์ ํด์ ์๊ทธ๋์ ๋ชฉ์ ์ง ํ๋ก์ธ์ค๋ก ๋ณด๋ ๋๋ค.
์ปค๋์ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ์๊ทธ๋์ ๋ณด๋ ๋๋ค.
- ์ปค๋์ด divide by zero(SIGFPE)๋ ์์ ํ๋ก์ธ์ค์ ์ข ๋ฃ(SIGCHLD)์ ๊ฐ์ ์์คํ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ์ ๋
- ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ kill ์์คํ ์ฝ์ ํธ์ถํด์ ์ปค๋์ด ๋ชฉ์ ์ง ํ๋ก์ธ์ค๋ก ์๊ทธ๋์ ๋ณด๋ผ ๊ฒ์ ์์ฒญํ์ ๋
๐ง ์๊ทธ๋ ์์
๋ชฉ์ ์ง ํ๋ก์ธ์ค๋ ์ ๋ฌ๋ ์ ํธ์ ๋ํด์ ์ปค๋์ด ์ด๋ค ๋ฐฉ์์ผ๋ก๋ ๋ฐ์ํ์ฌ์ผ ํ ๋ ์๊ทธ๋์ ์์ ํ๋ค๊ณ ํฉ๋๋ค.
๋ค์์ ์๊ทธ๋์ ๋ฐ์์ ๋ ์ทจํ ์ ์๋ ์ธ๊ฐ์ง ๋ฐ์์ ๋๋ค.
- ๋ฌด์(Ignore) : ์๋ฌด๊ฒ๋ ํ์ง ์์ต๋๋ค.
- ๋์ ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃ (with optinal core dump)
- ์๊ทธ๋ ํธ๋ค๋ฌ(์ฌ์ฉ์ ์์ค์ ํจ์)๋ฅผ ํธ์ถํ์ฌ ์๊ทธ๋์ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ด๋ ๋น๋๊ธฐํ ์ธํฐ๋ฝํธ์ ๋ํ ์๋ต์ผ๋ก ํธ์ถ๋๋ ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ ๋ฐฉ์๊ณผ ์ ์ฌํฉ๋๋ค. (์ฆ ์๊ทธ๋ ํธ๋ค๋ฌ๋ฅผ ์คํ์ํจ ํ ๊ธฐ์กด ํ๋ก์ธ์ค์์ ์คํํ ๋ช ๋ น์ด์ ๋ฐ๋ก ๋ค์ ๋ช ๋ น์ด๋ก ๋ฐํํฉ๋๋ค.)
๐ง Pending
์ก์ (์ ์ก)ํ์์ง๋ง ์์ง ์์ ๋์ง ์์ ์๊ทธ๋์ ํ๋ฉ(Pending) ์๊ทธ๋์ด๋ผ ๋ถ๋ฆ ๋๋ค.
(pending์ ๋๊ธฐ์ค์ด๋ผ๋ ๋ป์ ๋๋ค.)
์ด๋ ํน์ ํ ์๊ทธ๋์ ๋ํด์๋ ์ต๋ ํ ๊ฐ์ ์๊ทธ๋๋ง์ด ์กด์ฌํ ์ ์์ต๋๋ค.
์ฆ ์๊ทธ๋์ ํ ๊ฐ์ ๊ณณ์ ๋ค์ด๊ฐ ๋๊ธฐํ๋ ๊ฒ์ด ์๋๋ฏ๋ก, ๋ง์ผ ์ด๋ค ํ๋ก์ธ์ค๊ฐ ํน์ ํ์ ์ pending ์๊ทธ๋์ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ๋ค์์ ํด๋น ํ๋ก์ธ์ค๋ก ์ ๋ฌ๋๋ k ํ์ ์ ์๊ทธ๋๋ค์ ๋ฌด์๋ฉ๋๋ค.
ํ๋ก์ธ์ค๋ ํน์ ์๊ทธ๋์ ์์ ์ ๋ธ๋ก(block)ํ ์ ์์ต๋๋ค.
block๋ ์๊ทธ๋๋ค์ ์ ๋ฌ๋ ์ ์์ง๋ง, ํด๋น ์๊ทธ๋์ block์ด ํ๋ฆด ๋๊น์ง๋ ์์ ๋ ์ ์์ต๋๋ค.
์ด๋ SIGKILL(9), SIGSTOP(19)์ ํ๋ก์ธ์ค์์ block๋ ์ ์๋ ์๊ทธ๋์ ๋๋ค.
pending ์๊ทธ๋์ ์ต๋ ํ๋ฒ๋ง ์์ ํ ์ ์์ต๋๋ค.
๊ฐ ํ๋ก์ธ์ค์ ๋ํ์ฌ ์ปค๋์ pending ๋นํธ ๋ฒกํฐ๋ด์ ๋๊ธฐํ๊ณ ์๋(pending) ์๊ทธ๋์ ์งํฉ์ ๊ด๋ฆฌํ๋ฉฐ,
blocked ๋นํธ ๋ฒกํฐ ๋ด์์ block๋ ์๊ทธ๋์ ์งํฉ์ ๊ด๋ฆฌํฉ์ง๋ค.
๐ง ์๊ทธ๋์ ๊ตฌํ
์ปค๋์ ๊ฐ ํ๋ก์ธ์ค์ ์ปจํ ์คํธ์ pending๊ณผ blocked ๋นํธ ๋ฒกํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
pending์ ๋๊ธฐ ์๊ทธ๋๋ค์ ํ์ํฉ๋๋ค.
์ปค๋์ id = k์ธ ์๊ทธ๋์ด ๋์ฐฉํ ๋๋ง๋ค, pending ๊ฐ์ k๋ฒ์งธ ๋นํธ๊ฐ 1๋ก ์ค์ ๋ฉ๋๋ค.
์ปค๋์ id = k์ธ ์๊ทธ๋์ ์์ ํ ๋๋ง๋ค, pending ๊ฐ์ k๋ฒ์งธ ๋นํธ๋ฅผ 0์ผ๋ก ์ค์ ํฉ๋๋ค.
blocked๋ ๋ธ๋ก๋ ์๊ทธ๋๋ค์ ํ์ํฉ๋๋ค.
sigprocmask ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ฉ ํ๋ก๊ทธ๋จ์ด 1 ๋๋ 0์ผ๋ก ์ค์ ํฉ๋๋ค.
๐ง ํ๋ก์ธ์ค ๊ทธ๋ฃน
Unix ์์คํ ์ ์๊ทธ๋์ ํ๋ก์ธ์ค๋ก ๋ณด๋ด๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
์ด๋ ๋ชจ๋ ๋ฉ์ปค๋์ฆ์ ํ๋ก์ธ์ค ๊ทธ๋ฃน ๊ฐ๋ ์ ์ฌ์ฉํฉ๋๋ค.
๋ชจ๋ ํ๋ก์ธ์ค๋ ์ ํํ ํ ๊ฐ์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ ์ํ๋ฉฐ, ์ด๊ฒ์ ์์ process group ID(pgid)๋ก ์๋ณํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์์์ ๋ถ๋ชจ์ ๊ฐ์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ ์ํ๋ฉฐ, ์์ ๊ฐ๊ฐ์ job(์์ด ์ ๊ณตํ๋ ํ๋ก์ธ์ค์ ๋ํ ์ถ์ํ)๋ง๋ค ๋ณ๋์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ ๋ง๋ญ๋๋ค.
#include <unistd.h>
pid_t getpgrp(void);
getpgrp() ํจ์๋ ํ์ฌ ํ๋ก์ธ์ค์ ํ๋ก์ธ์ค ๊ทธ๋ฃน ID๋ฅผ ๋ฆฌํดํฉ๋๋ค.
#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
setpgid() ํจ์๋ฅผ ํตํด ํ๋ก์ธ์ค pid์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ pgid๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ด๋ ๋ง์ฝ pid๋ก ๋์ด๊ฐ๋ ๊ฐ์ด 0์ธ ๊ฒฝ์ฐ ํ์ฌ ํ๋ก์ธ์ค์ PID๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๋ง์ฝ pgid๊ฐ 0์ด๋ผ๋ฉด pid๋ก ๋ช ์๋ ํ๋ก์ธ์ค์ PID๊ฐ ํ๋ก์ธ์ค ๊ทธ๋ฃน ID๋ก ์ฌ์ฉ๋ฉ๋๋ค.
๐ง kill ๋ช ๋ น์ ์ด์ฉํ ์๊ทธ๋ ๋ณด๋ด๊ธฐ
/bin/kill ํ๋ก๊ทธ๋จ์ ๋ค๋ฅธ ํ๋ก์ธ์ค ํน์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ผ๋ก ์์์ ์๊ทธ๋์ ๋ณด๋ ๋๋ค.
์๋ฅผ ๋ค์ด ๋ค์์ ๋ช ๋ น์ ์๊ทธ๋ 9๋ฒ(SIGKILL)์ ํ๋ก์ธ์ค 15213์ ๋ณด๋ ๋๋ค.
linux> /bin/kill -9 15213
PID ๋ฒํธ์ -๋ฅผ ๋ถ์ด๊ฒ ๋๋ฉด, ์๊ทธ๋์ด ํ๋ก์ธ์ค ๊ทธ๋ฃน ID ๋ด์ ๋ชจ๋ ํ๋ก์ธ์ค๋ก ๋ณด๋ด์ง๋๋ก ํฉ๋๋ค.
linux> /bin/kill -9 -15213
SIGKILL ์๊ทธ๋์ด ํ๋ก์ธ์ค ๊ทธ๋ฃน 15213 ๋ด์ ๋ชจ๋ ํ๋ก์ธ์ค์๊ฒ ๋ณด๋ด์ง๋๋ก ํ์์ต๋๋ค.
์ฌ๊ธฐ์ /bin/kill ๊ณผ ๊ฐ์ด ์์ ํ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ์ ์ ์ฃผ๋ชฉํด์ผ ํ๋๋ฐ, ์ด๊ฒ์ ์ผ๋ถ Unix ์์ด ์์ ๋ง์ ๋ด์ฅ kill ๋ช ๋ น์ด๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
kill ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํธ๊ธฐ ๋๋ฌธ์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋๋ ๊ฒ์ด ์๋,
kill๋ก ์ธํด ๋ณด๋ด์ง๋ ์์์ ์๊ทธ๋์ ์ข ๋ฅ๊ฐ 9(SIGKILL)์ด์๊ธฐ ๋๋ฌธ์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๊ฒ์ ๋๋ค.
๐ ํค๋ณด๋๋ก ์๊ทธ๋ ๋ณด๋ด๊ธฐ
ํค๋ณด๋๋ก ctrl + c (ctrl + z)๋ฅผ ๋๋ฅด๋ฉด, SIGINT(SIGTSTP) ์๊ทธ๋์ด ํฌ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ ๋ชจ๋ ์์ ์ผ๋ก ์ ์ก๋ฉ๋๋ค.
SIGINT : ๊ธฐ๋ณธ๋์์ ๊ฐ ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃ์ํต๋๋ค.
SIGTSTP : ๊ธฐ๋ณธ๋์์ ๊ฐ ํ๋ก์ธ์ค๋ฅผ ์ ์ง์ํต๋๋ค.
SIGSTOP๊ณผ SIGTSTP๋ ๋ค๋ฆ ๋๋ค.
๐ ctrl + c, ctrl + z ์์
ctrl + z์ ์ํ์ฌ ํฌ๊ทธ๋ผ์ด๋์์ ์คํ์ค์ธ ์คํ์ค์ธ ๋ชจ๋ ํ๋ก์ธ์ค๊ฐ ์ค์ง(STAT : T)๋ ์ดํ,
ctrl + c์ ์ํ์ฌ ์ข ๋ฃ๋์์์ ์ ์ ์์ต๋๋ค.
STAT์ ๋ค์๊ณผ ๊ฐ์ ์ํ๋ค์ด ์์ต๋๋ค.
S : sleeping
T : stopped
R : running
์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
void fork()
{
pid_t pid[N];
int i;
int child_status;
/* child process๋ฅผ N๊ฐ ์์ฑํฉ๋๋ค. */
for (i = 0; i < N; i++) {
if ((pid[i] = fork()) == 0) { // ์์ ํ๋ก์ธ์ค์ธ ๊ฒฝ์ฐ
while(1); // ๋ฌดํ ๋ฃจํ ์คํ (์ข
๋ฃ๋์ง ์์)
}
}
/* ์์ฑ๋ ํ๋ก์ธ์ค๋ค ๋ชจ๋์๊ฒ kill SIGINT(2)๋ฅผ ๋ณด๋
๋๋ค. */
for (i = 0; i < N; i++) {
printf("Killing proecess %d\n", pid[i]);
kill(pid[i], SIGINT);
}
for (i = 0; i < N; i++) {
pid_t wpid = wait(&child_status);
/* WIFEXITED ๋ exit ํธ์ถ ๋๋ return์ ํตํด์
* ์์์ด ์ ์์ ์ผ๋ก ์ข
๋ฃ๋์๋์ง ์ฒดํฌํฉ๋๋ค.(์ ์ ์ข
๋ฃ : true)*/
if (WIFEXITED(child_status)) {
printf(
"Child %d terminated with exit status %d\n",
wpid,
/* WEXITSTATUS ๋ ์ ์์ ์ผ๋ก ์ข
๋ฃ๋ ์์์ exit staus๋ฅผ ๋ฆฌํดํฉ๋๋ค.*/
WEXITSTATUS(child_status));
}
else {
printf("Child %d terminated abnormally\n", wpid);
}
}
}
์ ์ ์ข ๋ฃ๊ฐ ์๋ ์๊ทธ๋์ ํตํ ์ข ๋ฃ์ด๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค.
๐ง kill ํจ์๋ก ์๊ทธ๋ ๋ณด๋ด๊ธฐ
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
๋ง์ผ pid๊ฐ 0๋ณด๋ค ํฌ๋ฉด, kill ํจ์๋ ์๊ทธ๋ ๋ฒํธ sig๋ฅผ ํ๋ก์ธ์ค pid๋ก ๋ณด๋ ๋๋ค.
๋ง์ผ pid๊ฐ 0์ด๋ฉด kill์ ํธ์ถํ๋ ํ๋ก์ธ์ค์ธ ์์ ์ ํฌํจํด์ ํ๋ก์ธ์ค ๊ทธ๋ฃน ๋ด ๋ชจ๋ ํ๋ก์ธ์ค์ ์๊ทธ๋ sig๋ฅผ ๋ณด๋ ๋๋ค.
๋ง์ผ pid๊ฐ 0๋ณด๋ค ์์ผ๋ฉด kill์ ํ๋ก์ธ์ค ๊ทธ๋ฃน |pid|(์ ๋๊ฐ) ๋ด์ ๋ชจ๋ ํ๋ก์ธ์ค๋ก ๋ณด๋ ๋๋ค.
๐ง ์๊ทธ๋ ๋ฐ๊ธฐ
์ปค๋์ด ํ๋ก์ธ์ค p๋ฅผ ์ปค๋ ๋ชจ๋์์ ์ฌ์ฉ์ ๋ชจ๋๋ก ๋์์ค๋ ๊ฒฝ์ฐ(์ฆ ์์ธ์ฒ๋ฆฌ ํธ๋ค๋ฌ์์ ๋์์ค๋ ๊ฒฝ์ฐ, ํน์ ๋ฌธ๋งฅ ์ ํ์ ๋๋ง์น๋ ๊ฒฝ์ฐ ๋ฑ)๋ฅผ ์๊ฐํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
1. ์ปค๋์ ํ๋ก์ธ์ค p์ ๋ํ์ฌ ๋ธ๋ก๋์ง ์์ ํ๋ฉ ์๊ทธ๋(pending & ~blocked)์ ์งํฉ์ ์ฒดํฌํฉ๋๋ค.
2. ๋ง์ฝ ํ๋๋ผ๋ ์กด์ฌํ๋ ๊ฒฝ์ฐ, pending&~blocked ์ ๊ฒฐ๊ณผ(๋ธ๋ก๋์ง ์์ ํ๋ฉ ์๊ทธ๋๋ค)์์ 0์ด ์๋ ๋นํธ์ ๋ํ์ฌ, ํด๋น ๋นํธ๊ฐ k๋ฒ์งธ ๋นํธ์ธ ๊ฒฝ์ฐ ํ๋ก์ธ์ค p๊ฐ ์๊ทธ๋ k๋ฅผ ์์ ํ๋๋ก ํฉ๋๋ค.
ํ๋ก์ธ์ค p๋ ์๊ทธ๋์ ์์ ํ๋ฉด ์๊ทธ๋ ์ฒ๋ฆฌ ์์ ์ ์ํํฉ๋๋ค.
3. ๋ธ๋ก๋์ง ์์ ํ๋ฉ ์๊ทธ๋๋ค์ด ์กด์ฌํ์ง ์์ ๋๊น์ง ์ ๊ณผ์ ์ ๋ฐ๋ณตํฉ๋๋ค.
4. ๋ง์ผ ํด๋น ์งํฉ์ด ๋น์ด ์๋ค๋ฉด(๋ชจ๋ 0) ์ปค๋์ ์ ์ด๋ฅผ p์ $I_{next}$๋ก ์ ๋ฌํฉ๋๋ค.
๐ง ์๊ทธ๋ ํ์ ์ ๊ธฐ๋ณธ(Default) ๋์
๊ฐ ์๊ทธ๋ ํ์ ์ ์ฌ์ ์ ์ ์๋ ๊ธฐ๋ณธ ๋์์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ข ๋ฅ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํฉ๋๋ค.
ํ๋ก์ธ์ค๋ ์ข ๋ฃํ๊ณ ์ฝ์ด๋ฅผ ๋คํํฉ๋๋ค.
ํ๋ก์ธ์ค๋ SIGCONT ์๊ทธ๋์ ์ํด ์ฌ์์๋ ๋๊น์ง ์ ์งํฉ๋๋ค.
ํ๋ก์ธ์ค๋ ์๊ทธ๋์ ๋ฌด์ํฉ๋๋ค.
๐ง ์๊ทธ๋์ ๊ธฐ๋ณธ ๋์ ๋ณ๊ฒฝ - signal()
์์์ ์ดํด๋ณธ ๊ธฐ๋ณธ ๋์์ signal() ํจ์์ ์ํด ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ฐ, ํจ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
#include <signal.h>
typedef void (* sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
๊ทธ๋ฌ๋ SIGSTOP๊ณผ SIGKILL์ ๊ธฐ๋ณธ ๋์์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ธ์๋ก ๋์ด๊ฐ๋ handler์ ๋ฐ๋ผ ๊ธฐ๋ณธ ๋์์ ๋ค์ ์ธ ๊ฐ์ง ๋ฐฉ๋ฒ ์ค์ ํ๋๋ก ๋ฐ๊ฟ ์ ์์ต๋๋ค.
SIG_IGN : signum ํ์ ์ ์๊ทธ๋์ ๋ฌด์ํฉ๋๋ค.
SIG_DFL : ์๊ทธ๋ ํ์ signum์ ๊ธฐ๋ณธ ๋์์ผ๋ก ๋ณต๊ทํฉ๋๋ค.
์ด ์ธ์ ๊ฒฝ์ฐ handler๋ก ๋์ด๊ฐ๋ ๊ฐ์ ์๊ทธ๋ ํธ๋ค๋ฌ์ ์ฃผ์๊ฐ ๋์ด signum ์๊ทธ๋์ ์์ ํ ๋๋ง๋ค ์คํ๋ฉ๋๋ค.
ํธ๋ค๋ฌ์ ์ฃผ์๋ฅผ signal ํจ์๋ก ๋๊ฒจ์ฃผ๋ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ ๋์์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด๋ฏ๋ก ํธ๋ค๋ฌ๋ฅผ ์ค์นํ๋ค๋ผ๊ณ ๋งํฉ๋๋ค.
ํธ๋ค๋ฌ์ ํธ์ถ์ ์๊ทธ๋์ ๋ถ์ก๋๋ค(catching)๊ณ ๋ถ๋ฅด๋ฉฐ,
ํธ๋ค๋ฌ์ ์คํ์ ์๊ทธ๋์ ์ฒ๋ฆฌํ๋ค(handling)๊ณ ํฉ๋๋ค.
๐ ์๊ทธ๋ ํธ๋ค๋ฌ ์์
void int_handler(int sig)
{
printf("Process %d received signal %d\n", getpid(), sig);
exit(0);
}
void fork()
{
pid_t pid[N];
int i;
int child_status;
/* SIGINT(2) ์ ์ฒ๋ฆฌ๋ฅผ int_handler์ผ๋ก ๋ณ๊ฒฝ */
signal(SIGINT, int_handler);
}
์ด์ ๋ exit(0)์ผ๋ก ์ข ๋ฃ๋๊ธฐ ๋๋ฌธ์ ์ ์ ์ข ๋ฃ์ ๋๋ค.
๐ง ์๊ทธ๋ ํธ๋ค๋ฌ์ ์ด์๋์
int ccount = 0;
void child_handler(int sig)
{
int child_status;
pid_t pid = wait(&child_status);
ccount--;
printf("Received signal %d from process %d\n", sig, pid);
sleep(2);
}
void fork14()
{
pid_t pid[N];
int i;
int child_status;
ccount = N;
/* SIGCHLD : ์์์ด ์ ์ง ๋๋ ์ข
๋ฃ์ ๋ฐ์ */
signal(SIGCHLD, child_handler);
for (i = 0; i < N; i++) {
if ((pid[i] = fork()) == 0) {
sleep(1);
/* Child: Exit */
exit(0);
}
}
while (ccount > 0) {
pause();/* Suspend until signal occurs */
}
}
์ ํ๋ก๋จ์ ์ข ๋ฃ๋์ง ์์ต๋๋ค.
์๊ทธ๋์ ํ๋ฅผ ์ฌ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฌด์๋๋ ์๊ทธ๋์ด ์๊ธฐ๋ฏ๋ก ๋ฐ์ํ๋ ๋ฌธ์ ์ ์ ๋๋ค.
์ด๋ ๋ค์๊ณผ ๊ฐ์ด ํด๊ฒฐํ ์ ์์ต๋๋ค.
void child_handler2(int sig)
{
int child_status;
pid_t pid;
while ((pid = waitpid(-1, &child_status, WNOHANG)) > 0) {
ccount--;
printf("Received signal %d from process %d\n", sig, pid);
}
}
void fork() {
...
signal(SIGCHLD, child_handler2);
...
}
๐ง ์์ - ์ธ๋ถ์์ ์์ฑ๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํ๋ก๊ทธ๋จ(ctrl + c)
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
void handler(int sig)
{
printf("You think hitting ctrl-c will stop the bomb?\n"); sleep(2);
printf("Well...");
fflush(stdout);
sleep(1);
printf("OK\n");
exit(0);
}
main()
{
/* installs ctl-c handler */
signal(SIGINT, handler);
while(1) { }
}
๐ง ์์ - ๋ด๋ถ์์ ๋ฐ์๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํ๋ก๊ทธ๋จ
#include <stdio.h>
#include <signal.h>
int beeps = 0;
/* SIGALRM handler */
void handler(int sig)
{
printf("BEEP\n");
fflush(stdout);
if (++beeps < 5) {
alarm(1);
}
else {
printf("BOOM!\n");
exit(0);
}
}
main()
{
signal(SIGALRM, handler);
/* send SIGALRM in 1 second */
alarm(1);
while (1) {
/* handler returns here */
}
}
์ ์คํ ๊ฒฐ๊ณผ๋ BEEP๊ฐ 5๋ฒ ์ถ๋ ฅ๋ ์ดํ BOOM์ด ํฐ์ง๋ฉด์ ์ข ๋ฃ๋ฉ๋๋ค.
๐ง ํธ๋ค๋ฌ์ ์ค๋จ
ํธ๋ค๋ฌ๋ ๋ค๋ฅธ ํธ๋ค๋ฌ์ ์ํด ์ค๋จ๋ ์ ์์ต๋๋ค.
์๋๋ Main Process์์ ์๊ทธ๋ s์ ์ํด ํธ๋ค๋ฌ S๊ฐ ์คํ๋๊ณ ,
ํธ๋ค๋ฌ S๊ฐ ์คํ๋๋ ์ค๊ฐ์ ์๊ทธ๋ t๊ฐ ๋ฐ์ํ์ฌ ํธ๋ค๋ฌ T๊ฐ ๋ฐ์ํ๋ ์ํฉ์ ํํํ ๊ฒ์ ๋๋ค.
ํธ๋ค๋ฌ ์คํ ๋์ค ๋ค๋ฅธ ํธ๋ค๋ฌ๊ฐ ์คํ๋๋๋ผ๋, ๋ชจ๋ ์์ ์ ๋ง์น ํ์๋ ๋๋์์์ ๋๋จธ์ง ์์ ์ ์ํํฉ๋๋ค.
๐ง ์๊ทธ๋ ๋ธ๋กํ๊ธฐ์ ํด์ ํ๊ธฐ
๋ฆฌ๋ ์ค๋ ์ผ๋ฐ์ ์ผ๋ก ์๊ทธ๋์ ๋ฌต์์ ์ผ๋ก ๋ธ๋กํฉ๋๋ค.
์ปค๋์ ํ์ฌ ์ฒ๋ฆฌ์ค์ธ ์๊ทธ๋๊ณผ ๋์ผํ ๋๊ธฐ(pendding)์๊ทธ๋์ ๋ธ๋กํฉ๋๋ค.
์๋ฅผ ๋ค์ด SIGINT ํธ๋ค๋ฌ๋ ์ถ๊ฐ์ ์ธ SIGINT์ ์ํด์ ์ค๋จ๋์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ช ์์ ์ผ๋ก ์๊ทธ๋์ ๋ธ๋กํ๋ ๋ฐฉ๋ฒ๋ ์ ๊ณตํ๊ธฐ ์ํด sigprocmask ํจ์์, ํด๋น ํจ์์ ์ง์ํจ์๋ค์ ์ ๊ณตํฉ๋๋ค.
#include <signal.h>
int sigprocmask(int how, const sigset_t * set, sigset_t * oldset);
/* ๋ชจ๋ ์๊ทธ๋์ด ๋น์ด ์๋ ์งํฉ์ ์์ฑํฉ๋๋ค. */
int sigemptyset(sigset_t * set);
/* ๋ชจ๋ ์๊ทธ๋ ๋ฒํธ๋ฅผ 1๋ก ์ค์ ํฉ๋๋ค. */
int sigfillset(sigset_t * set);
/* ํน์ ์๊ทธ๋ ๋ฒํธ๋ฅผ 1๋ก ์ค์ ํฉ๋๋ค. */
int sigaddset(sigset_t * set, int signum);
/* ํน์ ์๊ทธ๋ ๋ฒํธ๋ฅผ 0์ผ๋ก ์ค์ ํฉ๋๋ค. */
int sigdelset(sigset_t * set, int signum);
sigprocmask ํจ์๋ how ๊ฐ์ ๋ฐ๋ผ ๋์์ด ๊ฒฐ์ ๋๋๋ฐ, ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
SIG_BLOCK(0) : set์ ์๋ ์๊ทธ๋๋ค์ blocked์ ์ถ๊ฐํฉ๋๋ค.
blocked = (blocked | set)
SIG_UNBLOCK(1) :set์ ์๋ ์๊ทธ๋๋ค์ blocked์์ ์ ๊ฑฐํฉ๋๋ค.
blocked = (blocked & ~set)
SIG_SETMASK(2) : blocked = set
sigprocmask์์ oldset์ด NULL์ด ์๋ ๊ฒฝ์ฐ ์ด์ ์ ์ฌ์ฉ๋๋ blocked ๋นํธ ๋ฐฑํฐ์ ๊ฐ์ด ์ ์ฅ๋ฉ๋๋ค.
๐ ์ฐธ๊ณ : ์๊ทธ๋ ๋ธ๋ฝ๊ณผ execve
์ ์ฌ์ง์ ํตํด ์ ์ ์๋ฏ์ด ์๊ทธ๋์ ๋ธ๋ฝ ์ํ๋ execve๋ฅผ ์ํํ๋๋ผ๋ ๋ณด์กด๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ์๊ทธ๋ ํธ๋ค๋ฌ๋ ๋ณด์กด๋์ง ์๊ณ ์ด๊ธฐํ๋ฉ๋๋ค.
๐ง ๋์์ฑ ๋ฌธ์ ์ ๋ฐ์
๋ค์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ๋ฌธ์ ์ ์ ํ์ธํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
void handler(int sig)
{
int olderrno = errno;
sigset_t mask_all; // ๋ชจ๋ ์๊ทธ๋ 1๋ก ๋ง๋ค mask
sigset_t prev_all; // ์ด์ ์๊ทธ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง mask
pid_t pid;
Sigfillset(&mask_all);
// ์ข๋น ์ ๊ฑฐํ ๊ฒฝ์ฐ
while( (pid = waitpid(-1, NULL, 0)) > 0 ) {
Sigprocmask(SIG_BLOCK, &mask_all, &prev_all); // ๋ชจ๋ ์๊ทธ๋ Block
deletejob(pid); // pid๋ฅผ job list์์ ์ ๊ฑฐ
Sigprocmask(SIG_SETMASK, &prev_all, NULL); //Block ์๊ทธ๋ ๋ณต๊ตฌ
}
if (errno != ECHILD) {
Sio_error("waitpid error");
}
errno = olderrno;
}
int main()
{
int pid;
sigset_t mask_all; // ๋ชจ๋ ์๊ทธ๋ 1๋ก ๋ง๋ค mask
sigset_t prev_all; // ์ด์ ์๊ทธ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง mask
Sigfillset(&mask_all); // 1๋ก ์ฑ์ฐ๊ธฐ
Signal(SIGCHLD, handler); // ํธ๋ค๋ฌ ์ค์น
initjobs();
while(1) {
if ((pid = Fork()) == 0 ) {
Execve("/bin/date", argv, NULL);
}
Sigprocmask(SIG_BLOCK, &mask_all, &prev_all);
addjob(pid);
Sigprocmask(SIG_SETMASK, &prev_all, NULL);
}
exit(0);
}
์ด๋ ๋ถ๋ชจ์์ addjob์ ํ๊ธฐ ์ ์ Child๊ฐ ๋จผ์ ์ข ๋ฃ๋์ด SIGCHLD ์ ํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด ๊ฒฝ์ฐ Handler์์๋ deletejob์ ํด์ฃผ๊ฒ ๋๋๋ฐ, ๋ถ๋ชจ์์ addjob์ ํ๊ธฐ ์ ์ด๋ผ ์๋ฌด ์ผ๋ ๋ฐ์ํ์ง ์์ผ๋ฉฐ,
์ดํ Handler๊ฐ ์ข ๋ฃ๋ ํ ๋ถ๋ชจ์์ addjob์ ์คํํ์ฌ ์กด์ฌํ์ง ์๋ ์์์ ์์ ๋ฆฌ์คํธํด ์ถ๊ฐํ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
void handler(int sig)
{
int olderrno = errno;
sigset_t mask_all; // ๋ชจ๋ ์๊ทธ๋ 1๋ก ๋ง๋ค mask
sigset_t prev_all; // ์ด์ ์๊ทธ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง mask
pid_t pid;
Sigfillset(&mask_all);
// ์ข๋น ์ ๊ฑฐํ ๊ฒฝ์ฐ
while( (pid = waitpid(-1, NULL, 0)) > 0 ) {
Sigprocmask(SIG_BLOCK, &mask_all, &prev_all); // ๋ชจ๋ ์๊ทธ๋ Block
deletejob(pid); // pid๋ฅผ job list์์ ์ ๊ฑฐ
Sigprocmask(SIG_SETMASK, &prev_all, NULL); //Block ์๊ทธ๋ ๋ณต๊ตฌ
}
if (errno != ECHILD) {
Sio_error("waitpid error");
}
errno = olderrno;
}
int main()
{
int pid;
sigset_t mask_all; // ๋ชจ๋ ์๊ทธ๋ 1๋ก ๋ง๋ค mask
sigset_t mask_one; // ๋ชจ๋ ์๊ทธ๋ 1๋ก ๋ง๋ค mask
sigset_t prev_one; // ์ด์ ์๊ทธ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง mask
Sigfillset(&mask_all); // 1๋ก ์ฑ์ฐ๊ธฐ
Sigemptyset(&mask_one); // ๋ชจ๋ 0
Sigaddset(&mask_one, SIGCHLD); // SIGCHLD๋ง 1
Signal(SIGCHLD, handler); // ํธ๋ค๋ฌ ์ค์น
initjobs();
while(1) {
// ๊ธฐ์กด SIGNAL์ ์ถ๊ฐ๋ก SIGCHLD๋ง Block
Sigprocmask(SIG_BLOCK, &mask_one, &prev_one);
if ((pid = Fork()) == 0 ) {
// SIGCHLD Block ํด์
Sigprocmask(SIG_SETMASK, &prev_one, NULL);
Execve("/bin/date", argv, NULL);
}
// ๋ชจ๋ SIGNAL Block
Sigprocmask(SIG_BLOCK, &mask_all, &prev_all);
addjob(pid);
Sigprocmask(SIG_SETMASK, &prev_all, NULL);
}
exit(0);
}
๐ง ๋ช ์์ ์ผ๋ก ์๊ทธ๋ ๋๊ธฐํ๊ธฐ
์ข ์ข ๋ฉ์ธ ํ๋ก๊ทธ๋จ์ ํน์ ์๊ทธ๋ ํธ๋ค๋ฌ์ ๋์์ ๋ช ์์ ์ผ๋ก ๊ธฐ๋ค๋ ค์ผ ํ ํ์๊ฐ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ์์ด ์ด๋ ํ foreground job์ ์์ํ ๋, ์ปค๋์ ์ด ์์ ์ด ์ข ๋ฃ๋๊ณ SIGCHLD ํธ๋ค๋ฌ์ ์ํด ์ญ์ ๋ ๋๊ฐ์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.
์๋๋ ์ด์ ํด๋นํ๋ ์์ ์ฝ๋์ ๋๋ค.
volatile sig_atomic_t pid;
void sigchld_handler(int sig)
{
int olderrno = errno;
pid = waitpid(-1, NULL, 0); //(2) pid ๊ฐ ๋ณ๊ฒฝ
errno = olderrno;
}
void sigint_hanlder(int sig) {}
int main(int argc, char ** argv)
{
sigset_t mask;
sigset_t prev;
Signal(SIGCHLD, sigchld_handler);
Signal(SIGINT, sigint_handler);
Sigemptyset(&mask);
Sigaddset(&mask, SIGCHLD);
while(1) {
// SIGCHLD Block
Sigprocmask(SIG_BLOCK, &mask, &prev);
if (Fork() == 0) {
// ์์์ธ ๊ฒฝ์ฐ ๋ฐ๋ก ์ข
๋ฃ -> SIGCHLD ๋ฐ์
exit(0);
}
// Parent ์ธ ๊ฒฝ์ฐ
pid = 0; //(1) : pid = 0 ์ผ๋ก ์ค์
// Unblock SIGCHLD
Sigprocmask(SIG_SETMASK, &prev, NULL);
// SIGCHLD ๊ธฐ๋ค๋ฆฌ๊ธฐ
while(!pid) {} // spin roop
printf(".");
}
printf("\n");
exit(0);
}
์ด๋ ์ ์์ ์ผ๋ก ์๋ํ์ง๋ง spin roop๋ ์์์ ๋ญ๋นํฉ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์คํ ๋ฃจํ ์์ pause()๋ฅผ ๋ผ์ ๋ฃ๋ ๋ฐฉ๋ฒ์ ์ทจํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด๋ ์๋์ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
'SIGCHLD Unblock -> while ์กฐ๊ฑด๋ฌธ ํ์ธ ์ดํ ๋ชธ์ฒด ์ง์ -> SIGCHLD ์๊ทธ๋ ํธ๋ค๋ฌ ์ํ -> pause() -> ์ดํ ์๊ทธ๋์ด ์์ด์ ๋ฌดํ ๋๊ธฐ'
์ด๋ฅผ pause ๋์ sleep(1)์ ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง๋ง, ์ด๋ ์ฑ๋ฅ์ด ๋๋ฌด ๋๋ ค์ง๋๋ค.
์ด์ ๊ฐ์ ๋ฌธ์ ์ ์ ์ ์ ํ ํด๊ฒฐ์ฑ ์ sigsuspend๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
๐ง sigsuspend
#include <signal.h>
int sigsuspend(const sigset_t *mask);
sigsuspend ํจ์๋ ํ์ฌ blocked ์๊ทธ๋ ์งํฉ์ ์ผ์์ ์ผ๋ก mask๋ก ๊ต์ฒดํ ๋ค,
์๊ทธ๋์ ์์ ํ ๋๊น์ง ์ ์ง์ํต๋๋ค.
์ด๋ ์๊ทธ๋์ ๋์์ด ์ข ๋ฃํ๋ ๊ฒ์ด๋ผ๋ฉด, ํด๋น ํ๋ก์ธ์๋ sigsuspend๋ก๋ถํฐ ๋ฆฌํดํ์ง ์๊ณ ์ข ๋ฃํฉ๋๋ค.
๋ง์ฝ ๊ทธ๋ ์ง ์๋ค๋ฉด sigsuspend๋ ํด๋น ์๊ทธ๋์ ํธ๋ค๋ฌ์์ ๋ฆฌํด๋ ํ blocked ์๊ทธ๋ ์งํฉ์ ์ด์ ์ ์งํฉ์ผ๋ก ๋ณต๊ตฌํฉ๋๋ค.
์ฆ ์ด๋ ์๋ ์ฝ๋๋ฅผ ์์์ ์ผ๋ก ์คํ์ํต๋๋ค.
sigprocmask(SIG_SETMASK, &mask, &prev); // mask์ ํด๋นํ๋ ์งํฉ์ผ๋ก blocked ๊ต์ฒด
pause(); // ์๊ทธ๋ ์์ ํ ๋๊น์ง ๋๊ธฐ
sigprocmask(SIG_SETMASK, &prev, NULL); // blocked ๋ณต๊ตฌ
์ด๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
volatile sig_atomic_t pid;
void sigchld_handler(int sig)
{
int olderrno = errno;
pid = waitpid(-1, NULL, 0); //(2) pid ๊ฐ ๋ณ๊ฒฝ
errno = olderrno;
}
void sigint_hanlder(int sig) {}
int main(int argc, char ** argv)
{
sigset_t mask;
sigset_t prev;
Signal(SIGCHLD, sigchld_handler);
Signal(SIGINT, sigint_handler);
Sigemptyset(&mask);
Sigaddset(&mask, SIGCHLD);
while(1) {
// SIGCHLD Block
Sigprocmask(SIG_BLOCK, &mask, &prev);
if (Fork() == 0) {
// ์์์ธ ๊ฒฝ์ฐ ๋ฐ๋ก ์ข
๋ฃ -> SIGCHLD ๋ฐ์
exit(0);
}
// Parent ์ธ ๊ฒฝ์ฐ
pid = 0; //(1) : pid = 0 ์ผ๋ก ์ค์
// Unblock SIGCHLD -> sigsuspend ์ฌ์ฉ ์ ํ์ ์์ด์ง
// Sigprocmask(SIG_SETMASK, &prev, NULL);
// SIGCHLD ๊ธฐ๋ค๋ฆฌ๊ธฐ
while(!pid) {
// sigsuspend ์ฌ์ฉ
// ๋จผ์ SIGCHLD๋ฅผ unblockํ๊ณ , pauseํ์
// ๋ค์ SIGCHLD๋ฅผ blockํ๋ค
sigsuspend(&prev);
}
// Optinally unblock SIGCHLD
// Sigprocmask(SIG_SETMASK, &prev, NULL);
printf(".");
}
printf("\n");
exit(0);
}
'๐ฅ Computer Science > ์์คํ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ๊ฐ์๋ฉ๋ชจ๋ฆฌ[1] - ๋์ ๋ฉ๋ชจ๋ฆฌ ํ ๋น (0) | 2022.12.01 |
---|---|
[์์คํ ํ๋ก๊ทธ๋๋ฐ] Shall Lab (0) | 2022.11.24 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ํ๋ก์ธ์ค [2] - ํ๋ก์ธ์ค์ ์ ์ด (0) | 2022.11.07 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ํ๋ก์ธ์ค [1] - ํ๋ก์ธ์ค (0) | 2022.11.07 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ํ๋ก์ธ์ค [0] - ์ ์ด ํ๋ฆ๊ณผ ์์ธ ์ํฉ (0) | 2022.11.07 |