* ํ๋ก์ธ์ค๋ฅผ ๊ณต๋ถํ๋ฉฐ ํท๊ฐ๋ฆฌ๋ ๋ถ๋ถ์ ์ ๋ฆฌํ๋ฉฐ ๊ณต๋ถํ ๊ฒ์ ๋๋ค. ์๋ชป๋ ๋ถ๋ถ์ ๋๊ธ๋ก ์๋ ค์ฃผ์ธ์
ํ๋ก์ธ์ค์ ํ๋ก๊ทธ๋จ, fork์ execve
๐ฒ ํ๋ก๊ทธ๋จ์ ์ฝ๋์ ๋ฐ์ดํฐ๊ฐ ํฉ์ณ์ง ๊ฒ. ๋์คํฌ ์์ ๋ชฉ์ ํ์ผ์ด๋ ์ฃผ์๊ณต๊ฐ์ ์ธ๊ทธ๋จผํธ๋ก ์กด์ฌ ๊ฐ๋ฅ
๐ฒ ํ๋ก์ธ์ค๋ ์คํ์ค์ธ ํ๋ก๊ทธ๋จ์ ํน์ ์ฌ๋ก์ด๋ค.
+ ํ๋ก์ธ์๋ CPU์ด๋ค.
๐ fork
๋ถ๋ชจ์ ๋ณต์ ๋ฅผ ์๋ก์ด ์์ ํ๋ก์ธ์ค์์ ๋์ผํ ํ๋ก๊ทธ๋จ์ ์คํํ๋ค.
๋ค๋ฅธ ์ปจํ ์คํธ - ๊ฐ์ ํ๋ก๊ทธ๋จ
signal mask ์์, signal handler ์์
๐ execve
์๋ก์ด ํ๋ก๊ทธ๋จ์ ํ์ฌ ํ๋ก์ธ์ค ์ปจํ ์คํธ ๋ด์์ ์คํ
๊ฐ์ ์ปจํ ์คํธ - ๋ค๋ฅธ ํ๋ก๊ทธ๋จ
signal mask ๋์ผ, signal handler ์ด๊ธฐํ
sleep๊ณผ pause์ ์ฐจ์ด
๐ถunsigned int sleep(unsigned int secs)
๐ฒ ์๊ธฐ ์์ ์ secs์ด ๋์ ์ ์ง(suspend) ์ํจ๋ค.
๐ฒ ์ ์์ ์ผ๋ก ๊นจ๋ฉด 0์ ๋ฆฌํดํ๊ณ , ๊ทธ ์ธ๋ ์์ฌ ์๊ฐ์ ๋ฆฌํดํ๋ค.
๐ถint pause(void)
๐ฒํธ์ถํ๋ ํ๋ก์ธ์ค๋ฅผ ์๊ทธ๋์ ๋ฐ์ ๋๊น์ง ์ ์ฌ์ด๋ค.
wait๊ณผ waitpid์ ์ฐจ์ด
๐ถ int wait(int *child_status)
๐ฒ ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์์ ํ๋ก์ธ์ค ์ค ํ๋๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ์ ์งํ๋ค.
๐ฒ ์์ ํ๋ก์ธ์ค๊ฐ ์ข๋น๊ฐ ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํด ๋ถ๋ชจ ํ๋ก์ธ์ค์์ ์คํํ๋ค.
๐ฒ ๋ฆฌํด ๊ฐ์ ์ข ๋ฃํ ์์ ํ๋ก์ธ์ค์ PID์ด๋ค.
๐ฒ child_status๊ฐ NULL์ด ์๋๋ฉด, ์์ ํ๋ก์ธ์ค์ ์ข ๋ฃ ์ด์ ๋ฅผ ๋ด๋๋ค.
๐ถ waitpid(pid, &status, options)
๐ฒ pid๋ -1์ด๋ฉด ๋๊ธฐ ์งํฉ์ ๋ชจ๋ ์์์ด๋ค.
๐ฒ pid๊ฐ > 0 ์ด๋ฉด ๋๊ธฐ ์งํฉ์ ํด๋น pid์ด๋ค.
๐ฒ options๊ฐ 0์ด๋ฉด, ๋๊ธฐ ์งํฉ์ ์์์ด ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
๐ฒ options๊ฐ 1์ด๋ฉด ์์์ด ์ข ๋ฃ๋์๋์ง ํ๋ฒ๋ง ํ์ธํ๋ค. 1 ๋์ WNOHANG์ ์ฐ๊ธฐ๋ ํ๋ค.
๐ฒ options๊ฐ 2์ด๋ฉด, ์ ์ง๋์๊ฑฐ๋ ์ข ๋ฃ๋ ์์์ ๊ธฐ๋ค๋ฆฐ๋ค. 2 ๋์ WUNTRACED๋ฅผ ์ฌ์ฉํ๊ธฐ๋ ํ๋ค.
์๊ทธ๋ ์์ ์์ 3๊ฐ์ง ๋ฐ์
1๏ธโฃ ๋ฌด์ํ๋ค .Ignore the signal
2๏ธโฃ ๋์ ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํ๋ค. (with optional core dump)
3๏ธโฃ ์๊ทธ๋ ํธ๋ค๋ฌ๋ผ๊ณ ๋ถ๋ฅด๋ ์ ์ ๋ ๋ฒจ ํจ์๋ฅผ ์คํํ์ฌ ์๊ทธ๋์ ์ก๋๋ค.(catch)
(๋น๋๊ธฐํ ์ธํฐ๋ฝํธ์ ๋ํ ์๋ต์ผ๋ก ํธ์ถ๋๋ ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ ๋ฐฉ์๊ณผ ์ ์ฌํ๋ค.)
์๊ทธ๋์ ์ค์ํ ํน์ง
๐ฒ ํน์ ํ์ ์ ์๊ทธ๋์ ๋ํด์๋ ์ต๋ ํ ๊ฐ์ ๋๊ธฐ ์๊ทธ๋์ด ์กด์ฌํ๋ค.
๐ฒ ์๊ทธ๋์ ํ์ ๋ค์ด๊ฐ์ง ์๋๋ค.
๐ฒ ์ฆ, ์ด๋ฏธ k ํ์ ์ ๋๊ธฐ ์๊ทธ๋์ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ์ดํ๋ก ๋ค์ด์ค๋ k ํ์ ์ ์๊ทธ๋์ ๋ฌด์๋๋ค.
๐ฒ ํ๋ก์ธ์ค๋ ํน์ ์๊ทธ๋์ ์์ ์ ๋ธ๋กํ ์ ์๋ค. ์ดํ, ๋ธ๋ก๋ ์๊ทธ๋์ ์ ๋ฌ๋ ์ ์์ผ๋ ํ๋ฆฌ๊ธฐ ์ ๊น์ง๋ ์์ ํ ์ ์๋ค.
๐ฒ ๋ธ๋กํ ์ ์๋ ์ ์ผํ ์๊ทธ๋์ SIGKILL์ด๋ค.
๐ฒ ๋๊ธฐ ์๊ทธ๋์ ๋ํ๋ด๊ธฐ ์ํด ๋นํธ ๋ฒกํฐ๋ฅผ ์ฌ์ฉํ๋ค.
๐ฒ pendding์ ๋๊ธฐ ์๊ทธ๋, blocked๋ ๋ธ๋ก๋ ์๊ทธ๋์ ์๋ฏธํ๋ค.
/bin/kill์ ํน์ง
๐ฒ ํ๋ก์ธ์ค ๋๋ ์์์ ํ๋ก์ธ์ค ๊ทธ๋ฃน์ ์๊ทธ๋์ ๋ณด๋ธ๋ค. SIGKILL์ ํ๋ ๊ฒ์ด ์๋๋ค.
๐ฒ kill -9 24818 : -9๊ฐ SIGKILL์ ๋ํ๋ด๋ ์๊ทธ๋ ๋ฒํธ์ด๋ฏ๋ก, PID๊ฐ 24818 ์ธ ํ๋ก์ธ์ค์ ํด๋น ์๊ทธ๋์ ์ ๋ฌํ๋ค.
์๊ทธ๋ ํ์ ์ ๊ธฐ๋ณธ ๋์๊ณผ ํธ๋ค๋ฌ ์ค์น
์๊ทธ๋ ํ์ ์ ๊ธฐ๋ณธ ๋์์ ์๋์ ๊ฐ๋ค.
๐ฒ ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํ๋ค.
๐ฒ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋๊ณ , coreํ์ผ์ ๋คํํ๋ค.(๋๋ฒ๊น ์ ์ํ ํ์ผ)
๐ฒ ํ๋ก์ธ์ค๊ฐ SIGCONT ์๊ทธ๋์ ์ํด ์ฌ๊ฐ๋ ๋๊น์ง ์ ์งํ๋ค.
๐ฒ ํ๋ก์ธ์ค๋ ์ด ์๊ทธ๋์ ๋ฌด์ํ๋ค.
์ด๋ฌํ ๊ธฐ๋ณธ๋์์ signal() ํจ์์ ์ํด์ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค. ๋จ, SIGSTOP๊ณผ SIGKILL์ ์์ธ์ด๋ค.
๐ถ handler_t *signal(int signum, hanlder_t *handler)
handler์ ๋ค์ด๊ฐ ์ ์๋ ๊ฐ์ ์๋์ ๊ฐ๋ค.
1๏ธโฃ SIG_IGN : signum ํ์ ์ ์๊ทธ๋์ ๋ฌด์ํ๋ค.
2๏ธโฃ SIG_DFL : ์๊ทธ๋ ํ์ signum์ ๊ธฐ๋ณธ ๋์์ผ๋ก ๋ณต๊ท
3๏ธโฃ ๊ทธ ์ธ์ ๊ฒฝ์ฐ, handler๋ signal_handler์ ์ฃผ์๊ฐ ๋๋ค.
๋ง์ฝ ํธ๋ค๋ฌ๊ฐ ๋ฆฌํด๋ฌธ์ ๋ง๋๋ค๋ฉด, ์ ์ด๊ถ์ ์๊ทธ๋์ ์ํด ์ข ๋ฃ๋์๋ ํ๋ก์ธ์ค์ ๋ค์ ๋ช ๋ น์ผ๋ก ๋์ด๊ฐ๋ค.
์๊ทธ๋ ํธ๋ค๋ฌ์ ์ด์ ๋์
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;
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 */
}
}
์ ํจ์๊ฐ ์ด์ ๋์ํ๋ ๊ฒ๋ ๋๊ธฐ ์๊ทธ๋๋ค์ ํ์ ๋ค์ด๊ฐ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฐ ์๊ทธ๋์ ๋๊ธฐ ์ฌ๋ถ๋ฅผ ํ์ํ๋๋ฐ๋ ํ๋์ ๋นํธ ๋ฒกํฐ๊ฐ ํ ๋น๋์ด ์๋ค๊ณ ํ์๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์์ SIGSHLD๋ฅผ ๋ณด๋ด๋๋ผ๋ SIGNAL์ด ์์ ํ ์์ ๋๊ธฐ ์ ๊น์ง ๊ฐ์ ํ์ ์ ์๊ทธ๋์ ๋ฌด์๋๋ค.
์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ ๋ต์ผ๋ก ์ฐ๋ฆฌ๋ waitpid๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
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);
...
}
๋ชจ๋ ์์ ํ๋ก์ธ์ค ์งํฉ์ ๋ํ์ฌ WNOHANG์ด๋ฏ๋ก ์์์ด ์ข ๋ฃ๋ ๊ฒ์ด ์์ ๋ ์ฆ์ ๋ฆฌํดํ๋ค. ์ฆ, ๋ชจ๋ ์์์ด ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์๋ค.
๋์์ฑ ๋ฌธ์
void handler(int sig)
{
int olderrno = errno;
sigset_t mask_all;
sigset_t prev_all;
int n = N; // N = 5;
pid_t pid;
Sigfillset(&mask_all);
while( (pid = waitpid(-1, NULL, 0)) > 0 ) {
// ๋ชจ๋ ์๊ทธ๋ Blockํ๊ธฐ
Sigprocmask(SIG_BLOCK, &mask_all, &prev_all);
deletejob(pid);
//Block ์๊ทธ๋ ๋ณต๊ตฌํ๊ธฐ
Sigprocmask(SIG_SETMASK, &prev_all, NULL);
}
if (errno != ECHILD) {
Sio_error("waitpid error");
}
errno = olderrno;
}
int main()
{
int pid;
sigset_t mask_all;
sigset_t prev_all;
Sigfillset(&mask_all);
Signal(SIGCHLD, handler);
initjobs();
while(n--) {
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);
}
๐ถ ๋ฌด์๊ณผ ๋ฌด์์ด race(๊ฒฝ์ฃผ)ํ๊ณ ์๋ ๊ฐ?
๋ถ๋ชจ ํ๋ก์ธ์ค์ main์ด ์งํ๋๋ฉฐ Sigpromask์์ SIGBLOCKํ๋ ค๋ ๊ฒ๊ณผ ์์ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋์ด SIGCHLD๊ฐ ํธ์ถ๋๋ ๊ฒ์ด ๊ฒฝ์ฃผํ๊ณ ์๋ค.
์ฆ, Blockํ๊ธฐ ์ ์ SIGCHLD๊ฐ ์คํ๋๊ฒ ๋๋ฉด ์์ ์ ๋ฑ๋ก๋ ํ๊ธฐ ์ ์ ์ข๋น ์ ๊ฑฐ๋ฅผ ํ๊ฒ ๋๋ฒ๋ฆฐ๋ค. ์ด๋ ์ํ์ง ์๋ ๋์์ด๋ค.
๋๋ฆ ๋ฒ ํ์ ์ผ๋ก addjob๊ณผ deletejob์ ํ๋ ค๊ณ ์๋์์น์ฒ๋ผ sigpromask๋ฅผ ํ์ฌ๋ 100๋ง๋ฒ์ ํ๋ฒ ๊ผด๋ก ์ด๋ฐ raceํ์์ด ๋ฐ์ํ๋ค๋ ๊ฒ์ด๋ค.
void handler(int sig)
{
int olderrno = errno;
sigset_t mask_all;
sigset_t prev_all;
int n = N; // N = 5;
pid_t pid;
Sigfillset(&mask_all);
// ์ข๋น ์ ๊ฑฐํ ๊ฒฝ์ฐ
while( (pid = waitpid(-1, NULL, 0)) > 0 ) {
Sigprocmask(SIG_BLOCK, &mask_all, &prev_all);
deletejob(pid); // pid๋ฅผ job list์์ ์ ๊ฑฐ
Sigprocmask(SIG_SETMASK, &prev_all, NULL);
}
if (errno != ECHILD) {
Sio_error("waitpid error");
}
errno = olderrno;
}
int main()
{
int pid;
sigset_t mask_all;
sigset_t mask_one;
sigset_t prev_one;
Sigfillset(&mask_all);
Sigemptyset(&mask_one);
// SIGCHLD๋ง 1๋ก ๋ง๋ ๋ค.
Sigaddset(&mask_one, SIGCHLD);
Signal(SIGCHLD, handler);
initjobs();
while(n--) {
// SIGNAL์์ SIGCHLD๋ง Block
Sigprocmask(SIG_BLOCK, &mask_one, &prev_one);
if ((pid = Fork()) == 0 ) {
// ์์์์๋ SIGCHLD UnBlock
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);
}
์์์ฒ๋ผ ์์์ ์์ฑํ๊ธฐ๋ ์ ์ ๋ ๋ค SIGCHLD๋ฅผ ๋ธ๋กํด์ค๋ค. ์ดํ์ ์์์ ๋ง๋ค๋ฉด, ๊ทธ๋๋ก SIGCHLD๋ฅผ ์ธ๋ธ๋กํด์ค๋ค. ์์์ ์๊ธฐ ๊ฐ๊ธธ ๊ทธ๋๋ก ๊ฐ๋ฉด ๋๊ธฐ ๋๋ฌธ์ด๋ค.
์ฆ, ๋ถ๋ชจ๋ ๊ทธ๋๋ก SIGCHLD๊ฐ ๋ธ๋ก๋ ์ํ์ด๋ค.(fork๋ signal mask๊ฐ ์์์ด๊ธฐ ๋๋ฌธ์ด๋ค.)
๊ทธ ์ํ์์ ๋ถ๋ชจ๋ ๋ชจ๋ ์๊ทธ๋์ ๋ํด ๋ธ๋ก์ ํด์ฃผ๊ณ addjob์ ํ์ฌ ํ์คํ๊ฒ ํด๋น PID๋ฅผ job์ ๋ฑ๋ก์ํจ๋ค.
์ด๋ ๊ฒ ํ๋ฉด "๊ฒฝ์ฃผ" ํ์์ ์์ด์ง๋ค. ์๋ํ๋ฉด, ๋ถ๋ชจ์์ SIGCHLD๋ ์ด๋ฏธ ๋ธ๋ก๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๋ช ์์ ์ผ๋ก ์๊ทธ๋ ๋๊ธฐํ๊ธฐ
volatile sig_atomic_t pid;
void sigchld_handler(int sig)
{
int olderrno = errno;
pid = waitpid(-1, NULL, 0);
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) {
exit(0);
}
pid = 0;
Sigprocmask(SIG_SETMASK, &prev, NULL);
while(!pid) {} // spin roop
printf(".");
}
printf("\n");
exit(0);
}
while๋ฌธ์ ์ดํด๋ณด์. Fork()๋ฅผ ํตํด ์์์ ์์ฑํ๋๋ฐ, ์์์ผ ๊ฒฝ์ฐ ๋ฐ๋ก ์ข ๋ฃํ๋ค. ์๋ฏธํ๋ ๋ฐ๋ SIGCHLD๋ฅผ ๋ฐ์์ํค๊ฒ ๋ค๋ ๋ป์ด๋ค.
๊ทธ๋ฐ๋ฐ, ๋ฐ๋ก ์์ค์ ๋ณด๋ Sigprocmask๋ก SIGCHLD๋ฅผ Block์์ผ์ฃผ์๋ค. ๋ฐ๋ผ์ SIGCHLD์ ๋ํ ํธ๋ค๋ฌ๊ฐ ๋ฐ๋ก๋ ์คํ๋์ง ์์ ๊ฒ์ด๋ค.
๋ถ๋ชจ ํ๋ก์ธ์ค๋ ๊ทธ๋๋ก ์งํํ๋ฉฐ, pid๋ฅผ 0์ผ๋ก ์ค์ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ SIGCHLD๋ฅผ ๋ค์ Unblock์์ผ์ฃผ๋๋ฐ, ์ด๋ ์๊น ๋ฐ์์์ผ Block๋์๋ SIGCHLD๋ฅผ ๊ทธ๋๋ก ๋ง๊ฒ ๋๋ค.
์ด๋ก์ธํด sigchld_hanlder๊ฐ ์คํ๋ ๊ฒ์ด๊ณ ์ข๋น ์ ๊ฑฐ๋ฅผ ์๋ํ๋ฉฐ pid ๊ฐ์ผ๋ก ํด๋น ์์ ํ๋ก์ธ์ค ์์ด๋๋ฅผ ๊ฐ์ง๋ค.
๋ค์ main์ผ๋ก ๋์์๋ณด์. ์ฌ๊ธฐ์ while(!pid) {}๋ฌธ์ ํตํด pid๊ฐ 0์ด๋ฉด ๋ฌดํ ๋ฃจํ๋ฅผ ๋๋ค. ์ฆ, ์์ ์ํํ๋ sigchld_handler์์ ์ข๋น์ ๊ฑฐ๊ฐ ์์ ํ ์ด๋ฃจ์ด ์ง ๋๊น์ง ๋ฌดํ ๋ฃจํ๋ฅผ ๋๋ค๋ ๊ฒ์ด๋ค.(spinning)
๊ทธ๋ฌ๋ ์ด๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์๋ํ๋ฉด ์ ์ฝ๋๋ SIGINT๋ก๋ ๋น ์ ธ๋์ค์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ค์ง pid์ ๊ฐ์ด ๋ณํ ๋๋ง ๋น ์ ธ๋์จ๋ค. ๋ํ while๋ก ์ธํ Instruction์ ๊ณ์ ์ํํ๊ณ ์๋ค. ํ์คํ ์ข์ง ์๋ค..
๊ทธ๋์ while ๋์ pause()๋ฅผ ๋ผ์๋ฃ๋ ๋ฐฉ๋ฒ์ ์๊ฐํ ์๋ ์๋ค. ํ์ง๋ง ์ด ๋ํ ๋ฌธ์ ๊ฐ ์๋ค.
SIGCHLD๊ฐ Unblock๋ ํ์ while ์กฐ๊ฑด๋ฌธ ํ์ธ ์ดํ ๋ชธ์ฒด์ ์ง์ ํ๋ค๊ณ ํด๋ณด์. ๋ง์ฝ ์ด๋ pause() ๊ฐ ์คํ๋๊ธฐ ์ ์ SIGCHLD ์๊ทธ๋ ํธ๋ค๋ฌ๊ฐ ์ํ๋๋ฉด, ๋ ์ด์ ์๊ทธ๋์ ๋ฐ์ํ์ง ์๋๋ค.
์ฆ, ์ดํ์ ๋ฐ์ํ๋ ์๊ทธ๋์ด ์์ด ๋ฌดํํ๊ฒ ๋๊ธฐํ๋ ๊ฒ์ด๋ค...
ํ๊ฐ์ง ๋ sleep(1)์ ์ฐ๋ ๋ฐฉ๋ฒ๋ ์๋ค. sleep์ ์ฌ์ฉํ๋ฉด pause์ ๋ฌธ์ ์ ์ ํด๊ฒฐ๋๋ ์ฑ๋ฅ์ด ๋์ ๋๋ ค์ง๋ค.
๊ทธ๋ฌ๋ฉด ๊ฒฐ๊ตญ ์ด๋ค ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ฌ์ผ ํ๋๊ฐ? ์ ๋ฌธ์ ๋ค์ ๋ํ ๋ชจ๋ ํด๊ฒฐ์ฑ ์ผ๋ก sigsuspend๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
sigsuspend๋ฅผ ์ฌ์ฉํ ์๊ทธ๋ ๊ธฐ๋ค๋ฆฌ๊ธฐ
#include <signal.h>
int sigsuspend(const sigset_t *mask);
sigsuspend ํจ์๋ mask์ ํด๋นํ๋ ์งํฉ์ผ๋ก block ์๊ทธ๋ ์งํฉ์ ์ผ์์ ์ผ๋ก ๊ต์ฒดํ๋ค. ๊ทธ ํ, ์๊ทธ๋์ ์์ ํ ๋๊น์ง pause()ํ๋ค. ์๊ทธ๋์ ์์ ํ๊ณ pause()๊ฐ ํ๋ฆฌ๋ฉด, ๋ค์ block์ ๋ณต๊ตฌํ๋ค.
์.. ์๊น์ ์ pause ์ฌ์ฉํ๋ฉด ๋ฌดํ ๋ฃจํ๋๋ค๊ณ ํ๋ค๋ฉด์ ์ด๋ป๊ฒ ๊ฐ๋ฅํ ๊ฒ์ด๋๊ณ ๋ฌผ์ ์ ์๋ค. ๊ทธ ์ด์ ๋ ๋ฐ๋ก ์ ๊ณผ์ ์ ์์์ ์ผ๋ก ์คํํ๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, ์ธํฐ๋ฝํธ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
์ฝ๋๋ก ๋ณด๋ฉด ์๋์ ๊ณผ์ ์ ์์ํ์ผ๋ก ๊ตฌํํ ๊ฒ๊ณผ ๋์ผํ๋ค.
sigprocmask(SIG_SETMASK, &mask, &prev); // blocked |= mask๋ฅผ ์ํ
pause(); // ์๊ทธ๋์ ์์ ํ ๋๊น์ง ๋๊ธฐ
sigprocmask(SIG_SETMASK, &prev, NULL); // sigsuspend ์ด์ ์ blocked๋ก ๋ณต์
volatile sig_atomic_t pid;
void sigchld_handler(int sig)
{
int olderrno = errno;
pid = waitpid(-1, NULL, 0);
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) {
Sigprocmask(SIG_BLOCK, &mask, &prev);
if (Fork() == 0) {
exit(0);
}
pid = 0;
while(!pid) {
sigsuspend(&prev);
}
printf(".");
}
printf("\n");
exit(0);
}
while๋ฌธ ์์ sigsuspend๋ฅผ ๋ฃ์ผ๋ฉด, ๊ฐ๋จํ๋ฉด์ race ์๋ ์ฝ๋๊ฐ ์์ฑ๋์๋ค.
์ด์ง ์๊ฐํด์ผ ํ ๊ฒ์ด prev๋ sigsuspend๋ฅผ ํธ์ถํ๊ธฐ ์ด์ ์ blocked ์ํ์ด๋ฏ๋ก SIG_BLOCK๋ ์ํ์ด๋ค. sigsuspend ๋ด์์์ mask๋ prev์ด๋ฏ๋ก, unblock ํ blockํ๋ ๊ณผ์ ์์ ์ ์ ์๋ค.
'๐ Knowledge > ์์คํ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ๋์ ๋ฉ๋ชจ๋ฆฌ ํ ๋น(Implicit, Explicit List) (0) | 2023.12.14 |
---|