프로세스 생성 및 삭제 실습(fork, exec[execl, execv], fork+exec, wait)
2018. 2. 5. 00:43
함수들의 자세한 내용은 리눅스 스터디 - 7의 글을 참조
1. fork 실습
- 실행을 위한 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 |
#include <stdio.h>
#include <stdlib.h> // for system(exit() etc...)
#include <unistd.h> // for execl(), fork()
#include <wait.h> // for wait()
int main()
{
int pid;
int counter = 1;
pid = fork();
if(pid < 0)
{ /* error occurred */
fprintf(stderr,"Fork Failed"); //파일을 지정하여 printf, 현재는 표준에러출력(모니터)
exit(-1); //에러로 인한 종료
}
else if (pid== 0)
{ /* child process */ //자식이면 0, 부모는 자식의 pid값을 받는다
printf("Child here!\n");
while(counter <6)
{
printf("Child num: %d\n", counter); //부모와 자식이 개별로 동작하는 것을 알 수 있다
counter++;
sleep(1); //잠시 잠들게함
}
}
else
{ /* parent process */
printf("i'm parent!\n");
while(counter <6)
{
printf("parent num: %d\n", counter); //부모와 자식이 개별로 동작하는 것을 알 수 있다
counter++;
sleep(1); //잠시 잠들게함
}
wait(NULL); //부모프로세스는 자식이 종료될때까지 대기
printf("process Complete!\n");
}
return 0;
}
|
cs |
- 실행결과
a.c(실행파일명을 실수로 .c를 붙였다..)를 백그라운드에서 실행, 실행중간에 ps -f로 부모와 자식의 pid, ppid를 확인한다
2. execl 실습
- 실행을 위한 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
#include <stdio.h>
#include <unistd.h>
//#include <stdlib.h> //system을 사용하기위한 헤더파일
int main()
{//int main(int argc, char *argv[])//명령행 인자를 받기위한 인자개수, 포인터배열
printf("execl start!!\n");
execl("/bin/ls", "ls", "-l", NULL);
//system("/bin/ls -l");
//system함수는 인수로 실행시킬 프로세스의 이름을 받아 그 프로세스를 호출한다
//원형은 int system(const char *argv); //실패시 0, 성공시 양수 리턴
printf("if you read this message, fail creating execl func..\n");
//execl함수를 사용하지 않으면 현재 프로세스를 덮어쓰지않기때문에, system이후 printf가 실행된다
return 0;
}
|
cs |
- 실행결과
execl을 사용한 경우
system을 사용한 경우
쉘에 ls -l명령을 입력한 경우
3. execv 실습
- 실행을 위한 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13 |
#include <stdio.h>
#include <unistd.h>
int main()
{//int main(int argc, char *argv[])//명령행 인자를 받기위한 인자개수, 포인터배열
char *argv[] ={ "ls", "-l", NULL};
printf("execv start!!\n");
execv("/bin/ls", argv); //execl은 인자를 하나하나 불러와야하지만 execv는 포인터배열로 불러온다
//execl("/bin/ls", "ls", "-l", NULL)와 같다
printf("if you read this message, fail creating execv func..\n");
return 0;
}
|
cs |
- 실행결과
4. fork+exec 실습
- 실행을 위한 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 |
#include <stdio.h>
#include <stdlib.h> // for system(exit() etc...)
#include <unistd.h> // for execl(), fork()
#include <wait.h> // for wait()
int main()
{
int pid;
int counter = 1;
pid = fork();
if(pid < 0)
{ /* error occurred */
fprintf(stderr,"Fork Failed"); //파일을 지정하여 printf, 현재는 표준에러출력(모니터)
exit(-1); //에러로 인한 종료
}
else if (pid== 0)
{ /* child process */ //자식이면 0, 부모는 자식의 pid값을 받는다
printf("Child here!\n");
printf("execl start!!\n");//자식 프로세스는 exec를 호출하여 새로운 프로세스를 생성하고 자식프로세스는 종료된다
//다른말로 자식프로세스는 exec를 호출하여 새로운 코드로 덮어쓰게된다(자식의 자식이아닌 새로운 프로세스로 변경)
execl("/bin/ls", "ls", "-l", NULL);
printf("if you read this message, fail creating execl func..\n");
}
else
{ /* parent process */
printf("i'm parent!\n");
wait(NULL); //부모프로세스는 자식(exec로 생성된)이 종료될때까지 대기
printf("process Complete!\n");
}
return 0;
}
|
cs |
- 실행결과
5. wait 실습
- 실행을 위한 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 |
#include <stdio.h>
#include <unistd.h> // for execl(), fork()
#include <wait.h> // for wait()
int main()
{
int status;
int counter = 1;
pid_t pid;
pid_t pid_child;
pid = fork();
switch(pid)
{
case -1:
{
printf( "Fork Failed\n");
return -1; //에러로 인한 종료
break;
}
case 0: //자식프로세스
{
printf("Child here!\n");
while(counter <6)
{
printf("Child num: %d\n", counter); //부모와 자식이 개별로 동작하는 것을 알 수 있다
counter++;
sleep(1); //잠시 잠들게함
}
return 99;
break;
}
default: //부모프로세스
{
printf( "i'm parent, waiting for Child process\n");
pid_child = wait(&status); //종료되면 wait는 자식프로세스의 pid를 반환한다
printf( "exit - Child PID is %d\n", pid_child);
if ( 0 == (status & 0xff)) //정상종료이면 0, 비정상종료면 시그널값
{
printf( "success exit, return of Child process is %d\n", status >> 8); //8번 시프트하여 자식프로세스가 반환한 값(99)을 출력
}
else
{
printf( "Unexpected exit, exit signal num is %d\n", status); //하위 8비트에 저장된 시그널값 출력
}
break;
}
}
return 0;
}
|
cs |
- 실행결과
'Study > Linux' 카테고리의 다른 글
한글설치 및 적용법 & printf에서 한글 출력시 깨지는 원인 (0) | 2018.02.10 |
---|---|
프로세스의 잘못된 종료상태 실습(zombie, orphan) (0) | 2018.02.05 |
리눅스 스터디 - 7 (0) | 2018.02.05 |
리눅스 스터디 - 6 (0) | 2018.02.04 |
정적, 동적 라이브러리 실습 (0) | 2018.01.22 |