Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 취약점
- wnourefresh
- DOCKER-USER
- architecture
- C언어
- mvwin
- NAPT
- cbpf
- level trigger
- ncurses
- doupdate
- Docker
- 어셈블리어
- ioctl
- packet filter
- BOF
- Compiler
- iptables
- epoll_wait
- wrefresh
- LOB
- packet flow
- epoll
- .net core 7
- .nret core 배포
- 풀이
- vtable
- REDIS
- edge trigger
- rfc5508
Archives
- Today
- Total
Tuuna Computer Science
[ 좀비 프로세스 ] 본문
[ 좀비 프로세서 ]
:: 실행이 종료 되었지만 아직 삭제되지 않은 프로세스를 말한다.
보통 프로세스는 exit 시스템콜을 호출하여 프로세스를 종료 시킨다.
그리고 자신에 대한 모든 자원을 해제 시킨다. 하지만 프로세스의 exit status 상태와 PID는 여전히 남아서 유지( kernel :: task struct)에 유지하게 됨.
그 이유는 부모 프로세스는 자식 프로세스에 대한 종료상태등을 가져올 수 있어서 자신의 자식프로세가 어떤 상태로 작업을 마쳤는지에 대한 정보를 확인할 수 있기 때문이다!
struct task_struct //task_struct 구조
{
/*
* offsets of these are hardcoded elsewhere - touch with care
*/
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
unsigned long flags; /* per process flags, defined below */
int sigpending;
mm_segment_t addr_limit; /* thread address space:
0-0xBFFFFFFF for user-thead
0-0xFFFFFFFF for kernel-thread
*/
....
long counter;
long nice;
int exit_code, exit_signal;
struct task_struct *next_task, *prev_task;
....
pid_t pid;
pid_t session;
}
프로세스의 PID와 종료값을 저장하고 있는 변수임 exit_code와 pid 변수
부모 프로세스는 이 2개의 값을 얻어옴으로서 자식 프로세스의 종료값을 얻어올 수 있다.
좀비 프로세스는 exit상태이기 때문에 메모리나 디스크 cpu자원을 소비하지 않는다. 허너 task_struct 구조체를 소비하여 시스템의 악영향
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main()
{
int pid;
int status;
pid = fork();
if (pid == 0)
{
sleep(5); //자식프로세서는 5초후 종료 ?
printf("I will be back %d\n", getpid());
exit(0);
}
else if (pid > 0)
{
printf("Im parent %d\n", getpid());
printf("Press any key\n");
getchar(); //입력을 받을때까지 getchar()영역에 블럭킹상태
}
else
{
perror("fork error :");
}
}
부모 프로세스가 wait()함수를 이용해서 자식프로세스를 정리하지 않았을 경우 발생
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int* status : 자식프로세스의 종료상태 정보
wait함수는 자식프로세스가 종료될때까지 현재 프로세스를 블럭킹 시키며, 자식이 종료되거나 시그널이 발생해서 시그널핸들러를 호출할때 return 된다.
만일 wait를 호출하기도 전에 자식프로세스가 이미 종료되어 좀비상태로 기다리고 있다면, 함수는 즉시 리턴한다 .
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int pid;
int status;
int spid;
pid = fork();
if (pid == 0)
{
sleep(5);
printf("I will be back %d\n", getpid());
return 1;
}
else if (pid > 0)
{
printf("Im parent %d\n", getpid());
printf("Press any key and wait\n");
getchar();
// 자식프로세스를 wait 한다.
// 자식프로세스의 종료상태는 status 를 통해 받아온다.
spid = wait(&status);
printf("자식프로세스 wait 성공 \n");
// 자식프로세스의 PID, 리턴값, 종료상태(정상종료혹은 비정상종료)를
// 얻어온다.
printf("PID : %d\n", spid);
printf("Exit Value : %d\n", WEXITSTATUS(status));
//해당 프로세스의 exit 값을 평가
printf("Exit Stat : %d\n", WIFEXITED(status));
//프로세스의 종료상태를 판단하며 정상종료가 되었다면 0이 아닌값을 return
}
else
{
perror("fork error :");
}
}
즉, 자식프로세스가 종료되었지만 exit status와 PID가 여전히 남아있어 좀비가 되니 자식프로세스가 종료되는 즉시 wait를 통해 부모 프로세서도 종료시켜서 좀비 프로세서를 막는것인가
-> 부모 프로세스가 좀비 프로세스의 종료상태를 회수하게 되면(wait 시스템콜을 호출을 통하여) 좀비 프로세스는 제거된다.
한마디로 fork()하면 어디선가 반드시 wait()를 꼭 해줘야 한다.
'System programing' 카테고리의 다른 글
리눅스 메모리에 대해 (0) | 2018.08.10 |
---|---|
system call (0) | 2018.06.11 |
[ 공유 메모리 ] (0) | 2018.06.09 |
[리눅스] 프로세스에 대해서 (0) | 2018.06.09 |
Comments