
์ด์์ฒด์ ์์ ์ฌ์ฉ์ ํ๋ก๊ทธ๋จ์ด ์ด์์ฒด์ ์ ์ปค๋์๊ฒ ํน์ ์๋น์ค๋ฅผ ์์ฒญํ ๋ ์ฌ์ฉํ๋ ์ธํฐํ์ด์ค์ ๋๋ค. ๊ฐ๋จํ ๋งํด, ์์คํ ํธ์ถ์ ํ๋ก๊ทธ๋จ์ด ์ด์์ฒด์ ์๊ฒ ์์ ์ ์ํํด ๋ฌ๋ผ๊ณ ์์ฒญํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
fork(), exec(), wait()์ ๊ฐ์ ๊ฒ๋ค์ ํ๋ก์ธ์ค ์์ฑ๊ณผ ์ ์ด(์ฆ, ํ๋ก์ธ์ค ๊ด๋ฆฌ)๋ฅผ ์ํ ์์คํ
ํธ์ถ์
๋๋ค.
fork๋ ์๋ก์ด ํ๋ก์ธ์ค๋ฅผ ์์ฑํฉ๋๋ค.exec๋ ์๋ก์ด ํ๋ก๊ทธ๋จ์ ์คํํฉ๋๋ค.wait๋ ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ์์ฑํ ์์ ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ๋๊ธฐํฉ๋๋ค. ์ฆ, ์์ ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋ช
๋ น์ด์
๋๋ค.exit()๋ ํ๋ก์ธ์ค๋ฅผ ์ข
๋ฃํ๋ ์ญํ ์ ํฉ๋๋ค.์๋ก์ด ํ๋ก์ธ์ค๋ฅผ ์์ฑํ ๋ ์ฌ์ฉ๋๋ฉฐ, ํ์ฌ ํ๋ก์ธ์ค(๋ถ๋ชจ)๋ฅผ ๋ณต์ ํ์ฌ ์๋ก์ด ํ๋ก์ธ์ค(์์)๋ฅผ ์์ฑํฉ๋๋ค. ์ด ํจ์๊ฐ ํธ์ถ๋๋ฉด ๋ ๊ฐ์ ๊ฑฐ์ ๋์ผํ ํ๋ก์ธ์ค๊ฐ ์คํ๋ฉ๋๋ค.
fork()๊ฐ ์ฑ๊ณต์ ์ผ๋ก ํธ์ถ๋๋ฉด ์์ ํ๋ก์ธ์ค์ PID๋ฅผ ๋ฐํํฉ๋๋ค.fork()์ ๋ฐํ ๊ฐ์ผ๋ก 0์ ๋ฐ์ต๋๋ค.#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
printf("pid : %d\n", (int) getpid()); // pid : 29146
int rc = fork(); // ์ฃผ๋ชฉ
if (rc < 0) { // (1) fork ์คํจ
exit(1);
}
else if (rc == 0) { // (2) child์ธ ๊ฒฝ์ฐ (fork ๊ฐ์ด 0)
printf("child (pid : %d)\n", (int) getpid());
}
else { // (3) parent case
printf("parent of %d (pid : %d)\n", rc, (int)getpid());
}
}
์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ถ๋ ฅ์ด ๋์ต๋๋ค:
pid:29146
parent of 29147 (pid:29146)
child (pid:29147)
์ถ๋ ฅ ์์๋ ๋น๊ฒฐ์ ์ ์ ๋๋ค. ์ฆ, ๋ถ๋ชจ์ ์์ ํ๋ก์ธ์ค์ ์คํ ์์๋ ์ด์์ฒด์ ์ ์ค์ผ์ค๋ฌ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.
ํด์: PID๋ ํ๋ก์ธ์ ์๋ณ์๋ก, UNIX ์์คํ
์์๋ PID๋ฅผ ํตํด ํ๋ก์ธ์ค์ ๋ช
๋ น์ ๋ด๋ฆฝ๋๋ค. fork()๊ฐ ์คํ๋๋ ์๊ฐ, ์๋ก์ด ํ๋ก์ธ์ค(์์)๊ฐ ์์ฑ๋๋ฉฐ, ์ด๋ ์์ฑ๋ ํ๋ก์ธ์ค๋ ๋ถ๋ชจ ํ๋ก์ธ์ค์ ๊ฑฐ์ ๋์ผํ ๋ณต์ฌ๋ณธ์ ๊ฐ๊ฒ ๋ฉ๋๋ค. ์ด ์์ ์์ ์ด์์ฒด์ ๋ ๋ ๊ฐ์ ํ๋ก๊ทธ๋จ์ด ๋์์ ๋์ํ๋ค๊ณ ์ธ์ํ๋ฉฐ, ๋ณต์ฌ ์ดํ์ ๋์์ fork()์์ ๋ฐํ๋ ์์๋ผ๊ณ ์ธ์ํฉ๋๋ค. ๊ทธ ์ดํ๋ ์ด fork()์ ๋ฐํ๊ฐ์ ํตํด ๊ตฌ๋ถ๋ฉ๋๋ค.
์ฆ, Parent์ fork()๊ฐ ๋ฐ์ํ๋ฉด์ Child๊ฐ ๋ณต์ฌ๋๊ณ Parent์ Child ๋ ๋ค์์ ๋ฐฉ๊ธ ์คํ๋ ํ๋ฒ์ fork ํ์์ ๋ํด์ ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฐํ๊ฐ์ ๋ด๋ณด๋ด rc์ ์ ์ฅ๋๋ค. ๊ทธ๋์ Parent์ fork()์๋ child์ pid ๊ฐ์ด ๋ฐํ๋๊ณ Child๋ 0์ ๋ฐํํ๋ค.
Parent์ child์ fork ๊ฐ์ด ๋ค๋ฅด๋ค๋ ์ ์ ๋งค์ฐ ์ ์ฉํ ๋ฐฉ์์ด๋ค.
ํ์ง๋ง ์ค์ผ์ค๋ฌ๊ฐ ๋ถ๋ชจ๋ฅผ ๋จผ์ ์คํํ ์ง ์๋์ง ํ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ฌ๋ผ์ง ์ ์์ต๋๋ค:
pid:29146
child (pid:29147)
parent of 29147 (pid:29146)
wait()๋ ์์ ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ๋ธ๋ก ์ํ๋ก ๋๊ธฐํ๊ฒ ๋ง๋๋ ์์
์
๋๋ค. ์ฆ, ์์ ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ๋ถ๋ชจ ํ๋ก์ธ์ค๋ CPU ์์์ ์ฌ์ฉํ์ง ์๊ณ ๋๊ธฐํฉ๋๋ค.
์์ ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋๋ฉด wait()๋ ์ข
๋ฃ๋ ์์ ํ๋ก์ธ์ค์ PID๋ฅผ ๋ฐํํฉ๋๋ค. ์์ ์์์ int wc = wait(NULL);์ ์ถ๊ฐํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ๋ฉ๋๋ค.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
printf("pid : %d\n", (int) getpid()); // pid : 29146
int rc = fork(); // ์ฃผ๋ชฉ
if (rc < 0) { // (1) fork ์คํจ
exit(1);
}
else if (rc == 0) { // (2) child์ธ ๊ฒฝ์ฐ (fork ๊ฐ์ด 0)
printf("child (pid : %d)\n", (int) getpid());
}
else { // (3) parent case
int wc = wait(NULL); // ์ถ๊ฐ๋ ๋ถ๋ถ
printf("parent of %d (wc : %d / pid : %d)\n", wc, rc, (int)getpid());
}
}
์ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
pid:29146
child (pid:29147)
parent of 29147 (wc:29147 / pid:29146)
wait()๋ฅผ ํตํด ์์์ ์คํ์ด ๋๋ ๋๊น์ง ๋๊ธฐํจ์ผ๋ก์จ, ๋ถ๋ชจ๊ฐ ๋จผ์ ์คํ๋๋๋ผ๋ wait()๋ ์์์ด ์ข
๋ฃ๋๊ธฐ ์ ์๋ ๋ฐํํ์ง ์์ผ๋ฏ๋ก ๋ฐ๋์ ์์์ด ์คํ๋ฉ๋๋ค.
exec()๋ ํ์ฌ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์๋ก์ด ํ๋ก๊ทธ๋จ์ผ๋ก ์์ ํ ๋ฎ์ด์์ฐ๋ ์์คํ
ํธ์ถ์
๋๋ค. ์ด ํจ์๊ฐ ํธ์ถ๋๋ฉด ํ์ฌ ํ๋ก์ธ์ค์ ์ฝ๋, ๋ฐ์ดํฐ, ํ, ์คํ ๋ฑ์ด ๋ชจ๋ ์๋ก์ด ํ๋ก๊ทธ๋จ์ผ๋ก ๋์ฒด๋ฉ๋๋ค.
์ค์ํ ์ ์ exec() ํจ์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ํธ์ถ๋๋ฉด ๊ธฐ์กด์ ํ๋ก์ธ์ค ์ฝ๋๋ ๋ ์ด์ ์คํ๋์ง ์์ผ๋ฉฐ, ์ฆ exec() ์ดํ์ ์ฝ๋๋ ์คํ๋์ง ์๊ณ ์๋ก์ด ํ๋ก๊ทธ๋จ์ด ์์๋ฉ๋๋ค.
๋จ์ fork()๋ ๋์ผํ ํ๋ก์ธ์ค์ ๋ด์ฉ์ ์ฌ๋ฌ ๋ฒ ๋์ํ ๋ ์ฌ์ฉํ๋ฉฐ, ์์ ํ๋ก์ธ์ค์์ ๋ถ๋ชจ์ ๋ค๋ฅธ ๋์์ ํ๊ณ ์ถ์ ๋๋ exec()๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. exec() ์ดํ์๋ ์คํํ ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋ฉ๋๋ค.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
printf("pid : %d\n", (int) getpid()); // pid : 29146
int rc = fork(); // ์ฃผ๋ชฉ
if (rc < 0) { // (1) fork ์คํจ
exit(1);
}
else if (rc == 0) { // (2) child์ธ ๊ฒฝ์ฐ (fork ๊ฐ์ด 0)
printf("child (pid : %d)\n", (int) getpid());
char *myargs[3];
myargs[0] = strdup("wc"); // ๋ด๊ฐ ์คํํ ํ์ผ ์ด๋ฆ
myargs[1] = strdup("p3.c"); // ์คํํ ํ์ผ์ ๋๊ฒจ์ค argument
myargs[2] = NULL; // end of array
execvp(myargs[0], myargs); // wc ํ์ผ ์คํ
printf("this shouldn't print out\n"); // ์คํ๋์ง ์์
}
else { // (3) parent case
int wc = wait(NULL); // ์ถ๊ฐ๋ ๋ถ๋ถ
printf("parent of %d (wc : %d / pid : %d)\n", wc, rc, (int)getpid());
}
}
exec()๊ฐ ์คํ๋๋ฉด execvp(์คํ ํ์ผ, ์ ๋ฌ ์ธ์) ํจ์๋ ์ฝ๋ ์ธ๊ทธ๋จผํธ ์์ญ์ ์คํ ํ์ผ์ ์ฝ๋๋ฅผ ์ฝ์ด์์ ๋ฎ์ด์์๋๋ค.
์์ด ์ดํ์๋ ํ, ์คํ ๋ฐ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์ด๊ธฐํ๋๊ณ , ์ด์์ฒด์ ๋ ์๋ก์ด ํ๋ก๊ทธ๋จ์ ์คํํฉ๋๋ค. ์ฆ, ์๋ก์ด ํ๋ก์ธ์ค๋ฅผ ์์ฑํ์ง ์๊ณ ํ์ฌ ํ๋ก๊ทธ๋จ์ wc๋ผ๋ ํ์ผ์ ์คํํฉ๋๋ค. ๊ทธ๋ก ์ธํด execvp() ์ดํ์ ๋ถ๋ถ์ ์คํ๋์ง ์์ต๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก, ์์ ํ๋ก์ธ์ค๋ exec()๋ฅผ ํธ์ถํ๊ณ ์คํํ๋ ์๊ฐ ์ข
๋ฃ๋๋ฉฐ, ๋ถ๋ชจ ํ๋ก์ธ์ค๋ ์ ์ง๋๋ค๊ฐ wait()์ ํตํด ์์์ด ์ข
๋ฃ๋ ํ ๊ทธ ์ดํ์ ์ฝ๋๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค.
[1] velog - [์ด์์ฒด์ ] ์์คํ
์ฝ๊ณผ ์ปค๋ ๋ชจ๋ (https://velog.io/@wejaan/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%BD%9C)
[2][ํ๋น๋ฏธ๋์ด] ํผ๊ณตํ์ต๋จ - [์ด์์ฒด์ ๋?] ์ปค๋์ ๊ฐ๋
, ์ด์ค ๋ชจ๋์ ์์คํ
ํธ์ถ (https://hongong.hanbit.co.kr/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EB%9E%80-%EC%BB%A4%EB%84%90%EC%9D%98-%EA%B0%9C%EB%85%90-%EC%9D%91%EC%9A%A9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%8B%A4%ED%96%89%EC%9D%84-%EC%9C%84%ED%95%9C/)
[3] Medium - ์ด์์ฒด์ ์ปค๋๋ชจ๋์ ์ฌ์ฉ์ ๋ชจ๋ ๋ฐ ์์คํ
ํธ์ถ (https://medium.com/@su_bak/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%BB%A4%EB%84%90%EB%AA%A8%EB%93%9C%EC%99%80-%EC%82%AC%EC%9A%A9%EC%9E%90-%EB%AA%A8%EB%93%9C-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%98%B8%EC%B6%9C-3631d24636a6)
[4] ํฐ์คํ ๋ฆฌ - [์ด์์ฒด์ ] ์ด์์ฒด์ (OS), ์์คํ
์ฝ(System Call) (https://brightstarit.tistory.com/13)