-
시스템 프로그래밍 실습 5주차 : ProcessesSystem Programming/Ubuntu Linux 2021. 9. 27. 18:22728x90
Processes
목차
Process란?
Procecss-related System calls
1. Creating a New Process
2. Destroying a Process
3. Synchronizing with Children
4. Running New Programs
Process란?
* Program과 Process와 Processor의 차이는?
-> Process는 실행 중에 있는 한 프로그램의 한 instance를 가리킨다, 또한 Processor에 의해 실행되고 있는 Program
-> Processor는 한 마디로 CPU를 가리키며, Program을 기억 장치로부터 읽어와 구동(데이터를 읽고, 연산 처리)시킨다
=> 즉 process는 각 program에 두 가지 abtraction들을 제공한다
1) Logical control flow 2) Private address space
https://giantpark197cm.tistory.com/44
1) Logical control flow
2) Private address space
< Procecss-related System calls >
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
1. Creating a New Process
pid_t fork(void)
- 부모 프로세스가 되고 새롭게 생성되는 프로세스는 자식 프로세스가 된다
- fork 함수에 의해 생성된 자식 프로세스는 부모 프로세스의 메모리를 그대로 복사하여 가지게 된다.
- 자식 프로세스에서는 return 0
- 부모 프로세스에서는 return 자식의 pid
https://codetravel.tistory.com/23
예제 1)
예상 출력
Parent has x = 0
Bye from process [부모 pid] with 0
Child has x = 2 # fork() 함수가 호출될 때, 부모 프로세스의 x값 1을 그대로 복사하기 때문에
Bye from process [자식 pid] with 0
예제 2)
예상 출력
L0
L1
Bye
L1
Bye
Bye
2. Destroying a Process
void exit(int status)
- 일반적으로 프로세스를 종료할 때 return문도 쓰지만, exit()함수를 사용하기도 한다
- exit() 함수에 들어 있는 인자 -1과 0 값은 부모 프로세스에게 종료 상태를 알려줄 수 있는 값이 된다.
- 부모 프로세스는 자식 프로세스의 종료 상태 값을 얻어서 자식 프로세스가 어떤 상태로 종료 되었는지를 알 수 있는 것
- 부모 프로세스는 자식의 종료 상태(정상/비정상)를 wait() 함수 또는 waitpid() 함수로 얻을 수 있다. (아래의 wait! )
-먼저 atexit() 함수에 등록된 모든 함수를 역순으로(즉, 등록된 마지막 함수가 호출되는 첫 번째 함수임) 호출한다.
- 프로그램을 종료하기 전에 버퍼를 모두 삭제하고 열린 파일을 모두 닫습니다.
atexit()
- exit(3)이나 프로그램 main()에서의 반환을 통한 정상적 프로세스 종료 시에 주어진 함수 function을 호출하도록 등록한다.
- 그렇게 등록한 함수들은 등록 역순으로 호출하며 아무 인자도 전달하지 않는다.
https://codetravel.tistory.com/28?category=993122
예제 )
예상 출력
cleaning up
3. Synchronizing with Children
pid_t wait(int *status)
- 부모 프로세스가 자식 프로세스의 종료 상태를 얻기 위해서는 wait() 함수를 사용!
- 즉, wait() 함수를 사용하여 자식 프로세스가 종료 될 때까지 기다릴 수 있다
- 만약 status!=NULL이면, the object it points to will be set to a status indicating why the child process terminated
1. 자식 프로세스가 동작 중이면 호출 차단이 차단되기 때문에 상태를 얻어올 때까지 대기
2. wait() 함수 호출자가 시그널을 받을 때까지 대기
3. 자식 프로세스가 종료된 상태라면 즉시 호출이 반환되어 상태를 얻음, 이 때 wait() 함수는 자식 프로세스의 프로세스 ID를 반환
4. 자식 프로세스가 없다면 호출이 즉시 반환되며, 에러값을 반환
https://codetravel.tistory.com/30?category=993122
pid_t waitpid(pid_t pid, int *status, int options)
- 특정한 process를 wait할 수 있다
- 다양한 options
- waitpid()에서 사용하는 pid인자값의 의미
- pid == 0 : 현재 프로세스의 프로세스 그룹ID와 같은 프로세스 그룹ID를 가지는 모든 자식 프로세스의 종료를 기다린다.
- pid > 0 : pid값에 해당하는 프로세스 ID를 가진 자식 프로세스의 종료를 기다린다.
- pid == -1 : 모든 자식 프로세스의 종료를 기다린다. 만약 pid값이 -1이면 waitpid함수는 wait()함수와 동일하다.
- pid < -1 : pid의 절대값과 동일한 프로세스 그룹ID의 모든 자식 프로세스의 종료를 기다린다.
https://codetravel.tistory.com/42?category=993122
https://reakwon.tistory.com/105
+) zombies
1) 고아 프로세스
- 부모 프로세스가 wait하여 자식 프로세스의 status를 가져가야 완전히 종료
- 부모 프로세스가 자식 프로세스보다 먼저 종료되면 자식 프로세스는 고아프로세스가 된다.
- 부모 프로세스가 자식 프로세스보다 먼저 종료되면 init 프로세스가 자식 프로세스 새로운 부모 프로세스가 된다.
- 종료되는 프로세스가 발생할 때 커널은 이 프로세스가 누구의 부모 프로세스인지 확인한 후, 커널이 자식 프로세스의 부모 프로세스 ID를 1(init 프로세스)로 바꿔 준다.
- 이때의 init 프로세스는 유닉스 계열의 운영체제에서 부팅 과정 중 생성되는 최초의 프로세스이며 시스템이 종료될때까지 계속 살아있는 데몬 프로세스이며, init 프로세스의 PID는 일반적으로 1이다
- 고아 프로세스가 작업을 종료하면 init 프로세스가 wait함수를 호출하여 고아 프로세스의 종료 상태를 회수함으로써 좀비 프로세스가 되는것을 방지
2) 좀비 프로세스
- 반대로 자식 프로세스가 부모 프로세스 보다 먼저 종료되는 경우
- 자식 프로세스가 종료되었지만 부모 프로세스가 자식 프로세스의 종료 상태를 회수하지 않았을 경우에 자식 프로세스를 좀비 프로세스라고 한다.
- 자식 프로세스가 종료된 이후에 부모 프로세스가 자식 프로세스의 상태를 알고 싶을 수 있기 때문에 커널은 자식 프로세스가 종료되더라도 최소한의 정보(프로세스 ID, 프로세스 종료 상태 등)를 가지고 있게 된다.
- 자식 프로세스가 exit 시스템 콜을 호출 하면서 종료되면 이 프로세스에 관련된 모든 메모리와 리소스가 해제되어 다른 프로세스에서 사용할 수 있게 됩니다.
- 부모 프로세스가 좀비 프로세스의 종료상태를 회수하게 되면(wait 시스템콜을 호출을 통하여) 좀비 프로세스는 제거됨
https://codetravel.tistory.com/31?category=993122
예제 1)
예상 출력
HP: hello from parent
HC: hello from child # 부모 프로세스 wait / 자식 프로세스 시작
Bye # 자식 프로세스 종료
CT: child has terminated # 부모 프로세스가 종료된 자식 프로세스 값 받음
Bye
예제 2)
자식 프로세스의 상태를 확인하는 매크로
- WIFEXITED(status) : 0이 아닌 값을 리턴하면 자식프로세스가 정상종료했다는 뜻
- WEXISTSTATUS(status) : WIFEXITED(status)매크로를 통하여 자식 프로세스가 정상종료했음을 확인하면 이 매크로를 통하여 종료 코드를 확인할 수 있다. 이 종료 코드는 exit()나 _exit()에서 인자로 주는 값을 말한다.
예제 3)
4. Running New Programs
execl()
execle()
execv()
execve()
- 현재의 프로세스에 다른 프로세스를 실행할 때 쓰이는 함수
- 즉, 현재의 프로세스에 실행할 프로세스를 덮어씌어버린다는 것
- exec 함수를 호출한 뒤로는 완전히 다른 프로세스가 된다는 뜻으로 해석- exec 함수 뒤에는 어떤 코딩을 하더라도 실행되지 않는다
- 그렇기 때문에 대부분 fork 함수를 사용하여 자식 프로세스를 생성한 후에 자식 프로세스에서 어떠한 프로세스가 수행되게끔 exec함수를 사용하는 경우가 많다.1. l, v : argv인자를 넘겨줄 때 사용합니다. (l일 경우는 char *로 하나씩 v일 경우에는 char *[]로 배열로 한번에 넘겨줌)
2. e : 환경변수를 넘겨줄 때 사용합니다. (e는 위에서 v와 같이 char *[]로 배열로 넘겨줍니다.)
3. p : p가 있는 경우에는 환경변수 PATH를 참조하기 때문에 절대경로를 입력하지 않아도 됩니다. (위에서 system함수 처럼)https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=bmw_rad&logNo=70176283594
https://bbolmin.tistory.com/35
https://m.blog.naver.com/youtoo2/20011337681
예제 1)
예제 2)
예제 3)
예상 출력
예제 4)
예상 출력
https://noel-embedded.tistory.com/1200
728x90'System Programming > Ubuntu Linux' 카테고리의 다른 글
시스템 프로그래밍 실습 7주차 : Signals (0) 2021.10.10 시스템 프로그래밍 실습 6주차 : Daemon (0) 2021.10.03 시스템 프로그래밍 실습 4주차 : File I/O (0) 2021.09.20 시스템 프로그래밍 실습 3주차 : Shell & Makefile & Git (0) 2021.09.16 시스템 프로그래밍 실습 2주차 : gcc & gdb (0) 2021.09.16