출처: https://3months.tistory.com/307 [Deep Play]

4-1/시스템프로그래밍

Process Control

코딩하는 랄뚜기 2022. 3. 15. 19:47

System Call Error Handling

 

당연히 System Call을 할 때 Error가 발생할 수 있기 때문에 Error 처리를 해줘야 한다.

fork()를 하다가 Error가 난 경우 Error처리

 

※System call에서 Exception만이 void return 값을 갖는다.

 

Error-reporting function을 이용하여 간단하게 표현 할 수 있다.

 

 

Error Handling이 되는 Fork함수

 

 


 

 

Creating and Terminating Processes

 

Process state는 4가지가 있다.

 

  1. Running - 현재 CPU에 의하여 실행되고 있는 상태이다.
  2. Waiting - Scheduling이 된 상태로 대기 중인 상태이다.
  3. Blocked (Stopped) - Scheduling이 되지 않은 상태로 Signal이 와야 Scheduling이 된다. Signal이 오지 않는다면 Scheuling이 될 수 없다.
  4. Terminated - 다시는 실행되지 않을 상태이다.

 


Creating Process

Parent processfork 함수를 이용하여 Child process를 만들 수 있다.

 

 

Fork() 함수를 이용하여 만들어진 Child process는 Parent process와 완전히 같은 내용을 담고 있다.

개별적인 Process가 만들어진 것이기 때문에 위 코드의 결과 값은 비확정적이다.( Child process가 먼저 실행되고 종료 될 수 있다. )

 

#include <stdio.h>
#include <unistd.h>

void fork4(){
	printf("L0\n");
	if(fork()!=0){
		printf("L1\n");
		if(fork()!=0){
			printf("L2\n");
		}
	}
	printf("Bye\n");
}

int main(){
	fork4();
	return 0;
}

 

위 코드의 Process Graph는 다음과 같다.

 

위 코드의 결과 값은 비확정적이나 나올 수 없는 순서(Infeasible output)가 존재한다.

 


 

Reaping Child Processes

 

Child Process terminte되면 CPU가 실행을 못하게 될 뿐이지 메모리에는 계속 올라와 있어 메모리 누수가 발생한다.

이렇게 terminate 되었지만 메모리에 올라와 있는 Process를 Zombie라고 부른다.

 

어떻게 하면 zombie process를 없앨 수 있을까?

Zombie process를 없애는 작업은 wait이나 waitpid를 사용하여 terminated child process의 Parent process가 하게 된다.

 

만약 Parent process가 child를 reap하지 않고 terminate된다면 메모리에서 제거 될 수 없는 Orphaned child가 생기게 되는데 wait을 사용하면 Orphaned child가 생기는 것을 방지 할 수 있다.

 


 

Wait : Synchronizing with Children

 

Wait을 사용하게 되면 Parent가 Child를 기다리게 된다. Process들이 종료되는데 순서가 생긴다는 의미이다.

 

#include <stdio.h>
#include <unistd.h>

void fork9(){
    int child_status;
    
    if(fork()==0){
        printf("HC : hello from child\n");
        exit(0);
    }else{
        printf("HP : hello from parent\n");
        wait(&child_status);
        printf("CT : child has terminated\n");
    }
    printf("Bye\n");
}

int main(){
	fork9();
	return 0;
}

 

위 코드는 Parent가 fork를 한 이후에 Chid를 기다리고 있다. 따라서 Bye는 무조건 마지막에 출력되야 한다.

 


 

execve: Loading and Running Programs

 

execeve 함수는 fork된 child process에서 부모코드가 아니라 새로운 파일을 실행하고 싶을 때 사용하는 코드이다.

 

int execeve(char *filename, char *argv[], char *envp[]) 3가지 변수를 받는다.

 

argv에는 argument의 list가 들어간다. argv[0]은 filename으로 고정이다.

envp에는 environment variable이 list로 들어간다.

 

 

※아래는 "/bin/ls -lt /usr/include"를 child process에서 execeve 할 때 stack의 구조이다.

 

'4-1 > 시스템프로그래밍' 카테고리의 다른 글

Unix I/O, RIO package  (0) 2022.04.04
Signal  (0) 2022.03.28
Shell  (0) 2022.03.22
Processes  (4) 2022.03.10
Exceptional Control Flow, Exception  (0) 2022.03.09