👩🏻💻개발공부/리눅스
9. 리눅스 프로세스(Process) 예제로 알아보기 🔍(1/2)
리미32
2022. 12. 11. 16:02
728x90
안녕하세요! 이번 포스팅에서는 리눅스 관련 개념인 프로세스의 예제를 다뤄보겠습니다~ 먼저 시작하기에 앞서 프로세스를 관리해줄 System Call들을 살펴보겠습니다!
1. Process Management System Calls
- getpid : 프로세스의 ID를 얻는다.
- getppid : 부모 프로세스의 ID를 얻는다.
- fork : child 프로세스를 만들기 위해 부모 프로세스를 복제한다.
- exec : code, data, stack 등을 replace를 교체한다.
- exit : 프로세스를 종료한다. 종료할 때 상태 변수를 바꾸기 위해 사용한다.
- wait : 자식 프로세스를 위해 대기한다.
2. fork() 출력 예제 [myfork]
fork 하는 순간 parent 프로세스에서 리턴 한 번, child 프로세스에서 리턴 한 번해서 리턴을 총 두번합니다! 밑의 코드는 fork()의 리턴값에 따라 자식 프로세스인지 부모 프로세스인지 구별해서 각각 프로세스의 pid를 출력하는 코드입니다.
- child → 0
- parent → child의 프로세스의 PID
- 실패 → -1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t v1;
v1= fork();
if(v1==0){ //child process
printf("I'm child \n");
printf("%d \n",v1);
printf("pid : %d, ppid: %d \n",getpid(),getppid());
}
else{
printf("I'm Parent \n");
printf("%d \n",v1);
printf("pid : %d, ppid: %d \n",getpid(),getppid());
}
return 0;
}
3. fork() 예제에 wait() 추가 [mywait()]
-> wait를 하지 않으면 좀비 프로세스가 생길 수 있다.
좀비 프로세스란? 종료된 child 프로세스는 parent 프로세스가 return 코드를 수락할 때까지 시스템을 떠날 수 없습니다. return을 하지 않은채로 시스템을 종료시킨다면, 자식 프로세스가 좀비 프로세스가 된다. 한마디로, 프로세스 자체는 종료되었지만 부모 프로세스가 wait() 을 호출하지 않아서 시스템 프로세스 테이블에 남아있는 상태입니다.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
pid_t v1;
v1= fork();
if(v1==0){ //child process
printf("I'm child \n");
printf("%d \n",v1);
printf("pid : %d, ppid: %d \n",getpid(),getppid());
}
else{
printf("I'm Parent \n");
printf("%d \n",v1);
int exitstatus; //추가
wait(&exitstatus); //추가
printf("pid : %d, ppid: %d \n",getpid(),getppid());
}
return 0;
}
4. zombie 프로세스 만들기 [myzombie]
부모 프로세스에서 wait()을 부르기 전에 무한반복을 걸어주면 좀비 프로세스가 생성된다.
- <defunct> : 좀비 프로세스
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
pid_t v1;
v1= fork();
if(v1==0){ //child process
printf("I'm child \n");
printf("%d \n",v1);
printf("pid : %d, ppid: %d \n",getpid(),getppid());
exit();
}
else{
printf("I'm Parent \n");
printf("%d \n",v1);
int exitstatus;
for(;;){} //추가
wait(&exitstatus);
printf("pid : %d, ppid: %d \n",getpid(),getppid());
}
return 0;
}
5. 프로세스 제작 사이에 숫자 프린트하기
- fork()과정 사이에 숫자 프린트 하는 코드를 넣는다.
- WEXITSTATUS() 매크로를 활용하면 exit code를 알 수 있다.
- fflush() -> printf의 경우 버퍼에 저장한 후 io디바이스에 출력하는 방식이라서 지연 시간이 있다. fflush를 붙일 경우 버퍼에 저장하지 않고 바로 내보내기 때문에 지연시간이 줄어든다.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
pid_t v1;
v1= fork();
if(v1==0){ //child process
printf("child pid : %d, ppid: %d \n",getpid(),getppid());
for(int i=0;i<100;i++){ //숫자 출력
printf("%d ",i);
fflush(NULL); //버퍼 비우기
}
printf("\n");
exit(101);
}
else{
int exitstatus;
for(int i=100;i<200;i++){ //숫자 출력
printf("%d ",i);
fflush(NULL); //버퍼 비우기
}
printf("\n");
wait(&exitstatus);
printf("pid : %d, ppid: %d \n",getpid(),getppid());
printf("exitcode: %d \n",WEXITSTATUS(exitstatus)); //WEXITSTATUS() : exit code를 알 수 있다.
}
return 0;
}
다음 포스팅에서 이어서 진행하겠습니다!!
728x90