프로그램 실행
프로세스의 생성 fork
-호출한 프로세스와 동일한 프로세스를 새로 생성하여 새로운 프로세스 ID를 할당
-부모(parent) 프로세스: fork를 호출한 프로세스
-자식(child) 프로세스: fork에 의해 생성되는 프로세스
프로그램의 실행 exec
-호출한 프로세스를 새로운 프로세스로 변경한다.
-호출 후의 프로세스 ID는 변하지 않는다.
-새로운 프로그램의 내용이 실행된다.
프로세스의 식별
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); 호출한 프로세스의 프로세스 ID를 반환
pid_t getppid(void); 호출한 프로세스의 부모 프로세스 ID를 반환
uid_t getuid(void); 실제 사용자 (real user) ID를 반환
uid_t geteuid(void); 유효 사용자 (effective user) ID를 반환
gid_t getgid(void); 실제 그룹 (real group) ID를 반환
gid_t getegid(void); 유효 그룹 (effective group) ID를 반환
pid_t, uid_t, gid_t는 typedef에 의해 int로 선언
프로세스의 생성 (fork)
-새로운 프로세스를 생성
-리턴 값 성공한 경우 자식 프로세스의 PID (부모), 0 (자식), 실패하면 -1, errno에 에러의 내용을 저장
-에러 값 EAGAIN: 시스템에서 허용하는 최대 프로세스의 수를 초과
ENOMEM: 새로운 프로세스를 위한 스왑(swap) 공간 부족
-fork 성공, 생성된 자식 프로세스와 부모 프로세스와 동일한 프로그램, fork 호출 다음 문장부터 동시에 실행
-자식 프로세스의 메모리 공간
//커널은 자식 프로세스를 프로세스 테이블에 등록하고 메모리를 할당
//텍스트 영역은 공유하고, 데이터, 힙, 스택 영역은 복사
//대부분의 시스템에서 데이터,힙,스택 영역을 바로 복사하지 않는다. fork 이후에 보통 exec이 호출되기 때문
//변형 시에 복사 (copy-on-write, COW) 방법을 사용
자식과 부모 프로세스의 구분, 리턴 값으로 구분 부모:생성된 자식 프로세스의 PID, 자식:0
for 함수의 반환 값
-부모 프로세스: 여러 자식 프로세스를 각 fork의 리턴 값으로 구분
-자식 프로세스 : getppid 함수를 이용하여 부모 프로세스 식별
-PID가 0인 프로세스: swapper(sched)로서 시스템 부팅 시 생성되며 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
|
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
static int glob=6; // external variable in initialized data
char buf[]="a write to stdout\n";
int main(void)
{
int var; //automatic variable on the stack
pid_t pid;
var =88;
if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1){
perror("write error"); return -1;}
printf("before fork\n"); //we don't flush stdout
if((pid=fork())<0)
perror("fork error");
else if(pid==0){ //child
glob++; //modify variables
var++;
}else
sleep(2); //parent
printf("pid=%d, glob=%d, var=%d\b",getpid(),glob,var);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
fork 후에 달라지는 속성
-fork 함수의 리턴 값
-프로세스 ID, 부모 프로세스 ID
-자식 프로세스의 tms_utime,tms_stime,tms_cutime,tms_cstime 값은 0으로 초기화
-부모 프로세스의 파일 잠금(file locks)은 상속되지 않는다.
-처리되지 않은 (pending) 알람(alarm)과 시그널은 자식 프로세스에서 초기화
for 함수의 일반적인 용도
- 동일한 프로그램의 실행, 같은 프로그램을 복제하여 부모와 자식이 각각 다른 코드 부분을 동시에 실행해야 하는 경우
예: 네트워크 서버 (network servers)
- 새로운 프로그램의 실행, 자식 프로세스는 fork후에 exec 함수를 호출하여 새로운 프로그램을 실행한다.
예: 쉘 (shells)
vfork 함수
-vfork 함수는 exec 함수를 통해 새로운 프로그램을 실행시킬 목적으로 자식 프로세스를 생성, 부모 프로세스의 메모리 영역을 모두 복사 하지 않는다.
-자식 프로세스는 exec 이나 exit 호출을 할 때가지 부모 프로세스의 메모리 영역에서 실행되며, 부모 프로세스는 실행을 멈춘다. 자식 프로세스가 항상 먼저 실행되는 것을 보장
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
|
#include <stdio.h>
#include <sys/types.h>
static int glob=6; //external variable in initalized data
int main(void)
{
int var; //automatic variable on the stack
pid_t pid;
var=88;
printf("before vfork\n"); //we don't flush stdio
if((pid=vfork())<0){
perror("vfork error");
return -1;
}
else if(pid==0){ //child
glob++; //modify parent's variables
var++;
_exit(0); //child terminates
}
//parent
printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
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
|
#include <sys/types.h>
static void f1(void),f2(void);
int main(void)
{
f1();
f2();
_exit(0);
}
static void f1(void)
{
pid_t pid;
if((pid=vfork())<0)
perror("vfork error");
//child and parent both return
}
static void f2(void)
{
char buf[1000]; //automatic variables
int i;
for(i=0;i<sizeof(buf);i++) buf[i]=0;\
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
프로세스에 대한 대기 (wait)
- 자식 프로세스의 종료 상태 값을 얻어내는 방법
- 프로세스가 종료하면 부모 프로세스에게 SIGCHLD 시그널을 전달하여 대기(block) 사애를 해제
- wait 함수의 동작
// 모든 자식 프로세스가 실행되고 있는 동안 대기한다(block).
//자식 프로세스가 종료하면 종료 상태 값과 함께 즉시 리턴
// 에러 발생시에는 즉시 리턴(자식 프로세스가 없는 경우)
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t, int *statloc, int options);
- 종료된 자식 프로세스가 있으면 종료 상태 값을 statloc에 저장, 리턴 값은 종료된 자식 프로세스의 PID
- 자식 프로세스가 여럿인 경우 그 중 하나만 종료해도 리턴
- 자식 프로세스가 없을 경우에는 -1을 리턴
- 시그널에 의해서도 리턴되며 errno에 EINTR 값을 저장
- waitpid 함수는 특정 자식 프로세스를 지정하여 기다릴 수 있으며, 단순 대기 (blocking)를 방지하는 옵션가능
waitpid 함수
- wait 함수와 다른 기능
//여러 자식 프로세스 중에서 특정 자식의 종료 상태 값을 얻을 수 있다.
//단순 대기(blocking)를 방지할 수 있다. (WNOHANG 옵션, pid로 지정한 프로세스가 아직 종료하지 않았더라도 대기하지 않고 바로 리턴한다. 리턴값은 0이다.)
//작업 제어를 지원한다. (WUNTRACED 옵션, 작업 제어가 지원되는 시스템에서 pid로 지정한 프로세스가 잠시 중단된 경우에도 리턴한다.)
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
|
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void errors(char *msg, int code);
void cleanupaction(void);
int main(int argc,char **argv)
{
pid_t pid;
int status;
if((pid=fork())>0){ //부모프로세스가 수행하는 부분
while(!waitpid(pid,&status, WNOHANG)){
printf("parent stauts : %d\n",status++);
sleep(1);
}
printf("parent child exit:%d\n",status);
}
else if(pid==0){ //child
sleep(5);
printf("bye child\n");
exit(1);
}
else
{
printf("failed to fork\n");
}
printf("Buy buy\n");
return 0;
}
void cleanupaction(void)
{
printf("Clean-up action\n");
}
void error(char *msg, int code)
{
perror(msg);
exit(code);
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
경쟁조건(race conditions)
- 제한된 자원에 대한 임의적 접근
//여러 개의 프로세스가 공유된 데이터에 대해 작업을 수행하려고 할 때, 수행 결과는 각 프로세스의 실행 순서에 따라 다르다.
//경쟁 조건의 해결, 프로세스 간의 통신 (시그널, IPC 등), 자원 잠금(lock)
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
|
#include <sys/types.h>
#include <stdio.h>
static void charatatime(char *);
int main(void)
{
pid_t pid;
if((pid=fork())<0){
perror("fork error"); return -1; }
else if (pid==0){
charatatime("output from child\n");
} else {
charatatime("output from parent\n");
}
return 0;
}
static void charatatime(char *str)
{
char *ptr;
int c;
setbuf(stdout,NULL); //set unbuffered
for(ptr=str;c=*ptr++;)
putc(c,stdout);
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs |
'딥러닝 기반 영상인식 개발 전문가 과정 > 리눅스' 카테고리의 다른 글
6월3일 sid 와 프로세스, 신호(Signal) (0) | 2019.06.03 |
---|---|
5월31일 실습 (0) | 2019.05.31 |
5월30일 시스템 환경설정과 자원제한 (0) | 2019.05.30 |
5월 30일 사용자와 그룹 (0) | 2019.05.30 |
5월30일 시간과 날짜 연산 (0) | 2019.05.30 |