Skip to content

Latest commit

ย 

History

History
153 lines (112 loc) ยท 4.71 KB

[OS] System Call (Fork Wait Exec).md

File metadata and controls

153 lines (112 loc) ยท 4.71 KB

[Operating System] System Call


fork( ), exec( ), wait( )์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์€ Process ์ƒ์„ฑ๊ณผ ์ œ์–ด๋ฅผ ์œ„ํ•œ System call์ž„.

  • fork, exec๋Š” ์ƒˆ๋กœ์šด Process ์ƒ์„ฑ๊ณผ ๊ด€๋ จ์ด ๋˜์–ด ์žˆ๋‹ค.
  • wait๋Š” Process (Parent)๊ฐ€ ๋งŒ๋“  ๋‹ค๋ฅธ Process(child) ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ช…๋ น์–ด์ž„.

Fork

์ƒˆ๋กœ์šด Process๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ.

๊ทธ๋Ÿฌ๋‚˜, ์ด์ƒํ•œ ๋ฐฉ์‹์ž„.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    printf("pid : %d", (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)", (int) getpid());
    }
    else {								// (3) parent case
        printf("parent of %d (pid : %d)", rc, (int)getpid());
    }
}

pid : 29146

parent of 29147 (pid : 29146)

child (pid : 29147)

์„ ์ถœ๋ ฅํ•จ (parent์™€ child์˜ ์ˆœ์„œ๋Š” non-deterministicํ•จ. ์ฆ‰, ํ™•์‹ ํ•  ์ˆ˜ ์—†์Œ. scheduler๊ฐ€ ๊ฒฐ์ •ํ•˜๋Š” ์ผ์ž„.)

[ํ•ด์„]

PID : ํ”„๋กœ์„ธ์Šค ์‹๋ณ„์ž. UNIX ์‹œ์Šคํ…œ์—์„œ๋Š” PID๋Š” ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ๋ช…๋ น์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•จ.

Fork()๊ฐ€ ์‹คํ–‰๋˜๋Š” ์ˆœ๊ฐ„. ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•˜๋‚˜ ๋” ์ƒ๊ธฐ๋Š”๋ฐ, ์ด ๋•Œ ์ƒ๊ธด ํ”„๋กœ์„ธ์Šค(Child)๋Š” fork๋ฅผ ๋งŒ๋“  ํ”„๋กœ์„ธ์Šค(Parent)์™€ (almost) ๋™์ผํ•œ ๋ณต์‚ฌ๋ณธ์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค. ์ด ๋•Œ OS๋Š” ์œ„์™€ ๋˜‘๊ฐ™์€ 2๊ฐœ์˜ ํ”„๋กœ๊ทธ๋žจ์ด ๋™์ž‘ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ , fork()๊ฐ€ return๋  ์ฐจ๋ก€๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๊ทธ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ ์ƒ์„ฑ๋œ Process (child)๋Š” main์—์„œ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ , if ๋ฌธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ์ฐจ์ด์ ์ด ์žˆ์—ˆ๋‹ค. ๋ฐ”๋กœ child์™€ parent์˜ fork() ๊ฐ’์ด ๋‹ค๋ฅด๋‹ค๋Š” ์ ์ด๋‹ค. ๋”ฐ๋ผ์„œ, ์™„์ „ํžˆ ๋™์ผํ•œ ๋ณต์‚ฌ๋ณธ์ด๋ผ ํ•  ์ˆ˜ ์—†๋‹ค.

Parent์˜ fork()๊ฐ’ => child์˜ pid ๊ฐ’

Child์˜ fork()๊ฐ’ => 0

Parent์™€ child์˜ fork ๊ฐ’์ด ๋‹ค๋ฅด๋‹ค๋Š” ์ ์€ ๋งค์šฐ ์œ ์šฉํ•œ ๋ฐฉ์‹์ด๋‹ค.

๊ทธ๋Ÿฌ๋‚˜! Scheduler๊ฐ€ ๋ถ€๋ชจ๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ• ์ง€ ์•„๋‹์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๋  ์ˆ˜ ์žˆ๋‹ค.

pid : 29146

child (pid : 29147)

parent of 29147 (pid : 29146)


wait

child ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ž‘์—…

์œ„์˜ ์˜ˆ์‹œ์— 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", (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)", (int) getpid());
    }
    else {								// (3) parent case
        int wc = wait(NULL)				// ์ถ”๊ฐ€๋œ ๋ถ€๋ถ„
        printf("parent of %d (wc : %d / pid : %d)", wc, rc, (int)getpid());
    }
}

pid : 29146

child (pid : 29147)

parent of 29147 (wc : 29147 / pid : 29146)

wait๋ฅผ ํ†ตํ•ด์„œ, child์˜ ์‹คํ–‰์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์คŒ. parent๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๋”๋ผ๋„, wait ()๋Š” child๊ฐ€ ๋๋‚˜๊ธฐ ์ „์—๋Š” returnํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ฐ˜๋“œ์‹œ child๊ฐ€ ๋จผ์ € ์‹คํ–‰๋จ.


exec

๋‹จ์ˆœ fork๋Š” ๋™์ผํ•œ ํ”„๋กœ์„ธ์Šค์˜ ๋‚ด์šฉ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋™์ž‘ํ•  ๋•Œ ์‚ฌ์šฉํ•จ.

child์—์„œ๋Š” parent์™€ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” exec๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
    printf("pid : %d", (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)", (int) getpid());
        char *myargs[3];
        myargs[0] = strdup("wc");		// ๋‚ด๊ฐ€ ์‹คํ–‰ํ•  ํŒŒ์ผ ์ด๋ฆ„
        myargs[1] = strdup("p3.c");		// ์‹คํ–‰ํ•  ํŒŒ์ผ์— ๋„˜๊ฒจ์ค„ argument
        myargs[2] = NULL;				// end of array
        execvp(myarges[0], myargs);		// wc ํŒŒ์ผ ์‹คํ–‰.
        printf("this shouldn't print out") // ์‹คํ–‰๋˜์ง€ ์•Š์Œ.
    }
    else {								// (3) parent case
        int wc = wait(NULL)				// ์ถ”๊ฐ€๋œ ๋ถ€๋ถ„
        printf("parent of %d (wc : %d / pid : %d)", wc, rc, (int)getpid());
    }
}

exec๊ฐ€ ์‹คํ–‰๋˜๋ฉด,

execvp( ์‹คํ–‰ ํŒŒ์ผ, ์ „๋‹ฌ ์ธ์ž ) ํ•จ์ˆ˜๋Š”, code segment ์˜์—ญ์— ์‹คํ–‰ ํŒŒ์ผ์˜ ์ฝ”๋“œ๋ฅผ ์ฝ์–ด์™€์„œ ๋ฎ์–ด ์”Œ์šด๋‹ค.

์”Œ์šด ์ดํ›„์—๋Š”, heap, stack, ๋‹ค๋ฅธ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด ์ดˆ๊ธฐํ™”๋˜๊ณ , OS๋Š” ๊ทธ๋ƒฅ ์‹คํ–‰ํ•œ๋‹ค. ์ฆ‰, ์ƒˆ๋กœ์šด Process๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ํ˜„์žฌ ํ”„๋กœ๊ทธ๋žจ์— wc๋ผ๋Š” ํŒŒ์ผ์„ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋กœ์ธํ•ด์„œ, execvp() ์ดํ›„์˜ ๋ถ€๋ถ„์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.