ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Linux] 멀티 Process, Signal, WDT
    프로그래밍/리눅스 시스템 2024. 4. 15. 01:30

     

    process 관련 리눅스 명령어

     

    프로세스 확인 명령어 (list 형태)

     

    $ ps -ef

    • e : 모든 사용자들이 구동 시킨 모든 프로세스를 보여준다.
    • f : 상세 정보를 출력한다. (full format)

     

    grep과 함께 사용하여 특정 프로세스에 대한 정보만 확인 가능

     

    $ ps –ef | grep [검색 프로그램명]

     

     

     

     

    프로세스 확인 명령어 (tree 형태)

     

    $ pstree

     

     

    htop (프로세스 뷰어이자 프로세스 관리자) 실행하기
    •  설치 

    $ sudo apt install htop –y

     

     

    • 실행

    $ htop

     

     

     

    현재 쉘에서 실행 시킨 background 작업의 목록 출력

     

    $ jobs

     

     

    background 프로세스를 포어 그라운드로 실행

     

    $ fg %숫자

     

     

     

    Multi process

     

    fork() : 자식 프로세스 생성

    pid_t fork(void)

    • 기능 : 자식 프로세스를 생성
    • 입력값 : 없다. (void)
    • 반환값 : pid_t 타입, 생성한 자식 프로세스의 PID 값을 반환 (자식 process에서는 0이 반환된다)
    • 필요 라이브러리 : #include <sys/types.h> & #include <unistd.h> 필요

     

     

    💡[참고] 프로세스의 종료 과정
    1. 프로세스가 종료된다. → State : Zombie 로 진입
      • 아직 Process Descriptor가 남아있음
      • 부모가 Descriptor를 제거 하기 전까지는 자식은 Zombie 상태로 머무름
    2. 자식 프로세스는 부모 프로세스에게 SIGCHLD Signal 을 보내 처리해줄 것을 요청함.
    3. 부모 프로세스는 SIGCHLD Signal을 받으면, 다음의 두 과정 중 하나를 수행함
      • 자식 프로세스의 자원이 정리될 때까지 기다려야 한다면, wait( ) System Call 호출한다. → 커널이 정리한다.
      • 자식 프로세스가 종료되는 것을 기다리지 않을 수 있다. (비동기적)

    즉,

    - 프로세스가 종료되면, 프로세스가 점유한 메모리를 정리해야 한다. 

    - 이때, 종료된 프로세스가 스스로 메모리를 정리하는 것이 아니라, 해당 프로세스의 부모 프로세스가 자원을 정리한다.

    - 이때, 종료되었음에도 불구하고 부모 프로세스가 처리해주지 않아 여전히 프로세스 테이블에 존재하는 상태를 Zombie상태라 한다.

     

     

    getpid() : 본인 프로세스의 pid를 반환

    pid_t getpid(void)

     

    getppid() : 부모 프로세스의 pid를 반환

    pid_t getppid(void)

     

     

     

    signal() : 시그널을 받는 함수. 

    ighandler_t signal(int signum, sighandler_t handler);

    • 기능 : 
    • 입력 값
      • signum : 시그널 번호. (매크로로 정의되어 있다.)
        [signum 예시]
        > SIGSTOP (19): 프로세스를 멈춘다. (T 상태).
        > SIGKILL (9): 프로세스를 강제로 종료시킨다.
        > SIGTERM (15): 프로세스에게 종료를 요청한다.
        > SIGINT (2): 인터럽트 신호를 보낸다 (=> 주로 Ctrl+C로 보낸다.)
        > SIGSEGV (11): 세그멘테이션 위반, 잘못된 메모리 접근
        > SIGHUP (1): 터미널 연결 손실 또는 로그아웃 시그널.
        > SIGUSR1 (10): 사용자 정의 신호 1.
        > SIGUSR2 (12): 사용자 정의 신호 2.
        > SIGPIPE (13): 파이프 끊김 신호.
        > SIGALRM (14): 알람 신호, 타이머 만료를 나타낸다.
      • handler : 시그널이 발생하면, 동작할 함수포인터. 해당 함수는 매개변수로 signum을 받아온다.
    • 반환값 : 해당 시그널에 대해 등록된 핸들러 함수 포인터
    • 필요 라이브러리 : <signal.h>

     

     

    ex) signal 수신

    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    
    void run(int num){
        printf("HO!\n");
    }
    
    int main(){
        signal(SIGUSR1, run); //signal() system call함수 : SIGUSR1이 오면, run 함수를 수행한다.
    	
        pid_t pid = getpid();
        printf("My PID : %d\n", pid); //본인의 pid를 출력한다.
    
        while(1) {
    	printf("HAHIHUHEHO!\n"); //print를 계속 수행한다.
    	sleep(1);
        }
        return 0;
    }

     

     

     

    kill() : 시그널을 보내는 함수

    int kill(pid_t pid, int sig);

    • 기능 : 프로세스에 시그널을 보낸다.
    • 입력값
      • pid : 시그널을 보낼 프로세스의 pid
        (🚨 프로세스의 pid는 실행될 때마다 변하기 때문에, 시그널을 받을 프로그램을 실행시켜 해당 프로세스의 pid를 확인한 뒤 알맞게 입력해야한다!)
      • sig : pid 프로세스에게 보낼 signum
    • 반환값 : 시그널 전송에 성공하면 0, 실패하면 -1을 반환
    • 필요 라이브러리 : <sys/types.h> & <signal.h>

     

    또는, command 창에서 signal을 직접 보낼 수도 있다.

    kill  -[보낼 시그널 번호]  [시그널을 받을 프로세스의 pid]

     

     

     

    ex) signal 송신

    #include <stdio.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <stdlib.h>
    
    int main() {
        //gogo 를 먼저 실행해서 pid를 확인 한 뒤 수정해서 빌드한다.
        pid_t target_pid = 865532;
    
        int ret = kill(target_pid, SIGUSR1); // system call 로 gogo 에게 SIGUSR1 을 보낸다.
    	//전송 성공시 0을 반환, 실패는 -1
        
        
        if (ret == 0) { //전송 성공
            printf("%d <- signal transmit!\n", target_pid);
        } 
        else { //전송 실패
            printf("Fail!\n");
    	exit(1);
        }
    
        return 0;
    }

     

     

     

     

    WDT (watch dog timer)

     

    alarm() : SIGALRM 시그널을 전송

    unsigned int alarm(unsigned int seconds)

    • 기능 : seconds 시간이 지나면, SIGALRM 시그널을 전송하게 한다.
    • 입력값 : seconds(초)
    • 반환값 :  이전에 설정된 알람 시간(초) (*만약 이전에 알람이 설정되어 있지 않았다면, 0이 반환됨)
    • 필요 라이브러리 : <unistd.h> 

     

    ex) SIGALRM 시그널 전송

    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    void gogo(){
        printf("WAKE UP!\n");
        exit(1);
    }
    
    int main(){
        signal(SIGALRM, gogo);
    
        printf("3 seconds\n");
        alarm(3); //WDT
        printf("wait....\n");
    
        while(1) sleep(1); //process die.. SEGFAULT Error
    
        return 0;
    }
Designed by Tistory.
-->