하나도 모르는 과제를 진행하는 것이 가장 많은 것을 얻어간다!

 


 

진행과정

 

 

  1. 사용할 수 있는 내장 함수에 대한 사용법 익히기
  2. 과제가 원하는 방식 찾기
  3. sigaction
  4. 구현

 

 


 

1. 사용할 수 있는 내장 함수에 대한 사용법 익히기

 

사용할 수 있는 내장 함수들은 아래와 같다.

  • write
  • signal
  • sigemptyset
  • sigaddset
  • sigaction
  • kill
  • getpid
  • malloc
  • free
  • pause
  • sleep
  • usleep
  • exit

 

여기서 익숙한 함수보다는 처음 보는 함수들이 더 많이 보인다. 하나씩 알아보자!

 

#inlcude <unistd.h>

write(int fd, const void *buf, size_t nbytes)

문자를 출력/입력하는 함수

 

getpid(void)

실행 중인 프로세스 ID를 구한다.

 

sleep(sec)

sec만큼 실행을 늦춘다.

 

usleep(micro sec)

micro sec만큼 실행을 늦춘다.

 

pause(void)

항상 -1을 반환하면서 errno에는 ERESTARTNOHAND(에러코드)로 설정

시그널을 수신할 때까지 대기 상태로 유지한다.

 

#include <siganl.h>

signal(int signum, void (*handler)(int))

signum 시그널 번호

void (*handler)(int) 시그널을 처리할 핸들러

시그널을 구분해서 어떻게 처리할지 확인하는 함수

 

sigemptyset(sigset_t *set)

set  시그널 집합 변수

실패할 시 -1 반환

시그널 집합 변수의 내용을 제거

 

sigaddset(sigset_t *set, int signum)

실패할 시 -1 반환

시그널 집합 변수에 signum을 추가한다.

 

sigaction(int signum, const stuct sigaction *act, struct sigaction *oldact)

act 새롭게 설정할 행동

oldact 이전에 설정한 행동

실패할 시 -1 반환

 

kill(pid_t pid, int signum)

pid 실행 중인 프로세스 ID

프로세스에 시그널을 보낸다.

 

#inlcude <stdlib.h>

아래의 함수들은 이전 과제에서 수도 없이 썼기에 스킵!

malloc

free

exit

 


2. 과제가 원하는 방식 찾기

 

진행하면서 알아야 할 signal의 성질을 먼저 알아보자.

 

프로세스가 시그널을 받게 되면 해당하는 기본적인 동작을 하거나, 무시하거나, 내가 정의한 함수를 통해 동작 방식을 바꿀 수 있다.

 

프로세스가 시그널을 받게 되었을 때, 보낸 곳에서 시그널을 제대로 받았는지 확인하지 않는다.

시그널을 처리 중일 때 다른 시그널을 받게 되면 무시된다.

 

시그널을 발생시키는 번호에서 SIGSTOP과 SIGKILL은 시그널을 받으면 프로세스를 멈추고 죽이는 것인데 우리가 사용하는 SIGINT처럼 제어할 수 있는 것이 아니다.

 

내가 본 과제에서 해야 할 것과 진행 과정을 알아보자!

우리는 client 와 server를 만들어야 하는데 이 둘은 서로 통신이 가능해야 한다.

시작할 때 server가 먼저 실행된 후에 client가 실행되어야 하는데

client가 실행되었을 땐 본인의 pid를 출력하고

입력 파라미터로 server의 pid와 전달할 문자열이 입력되어야 한다.

또한, server는 문자열을 전달받으면 출력해야 한다.

 

여기서 우리는 SIGUSR1과 SIGUSR2만 사용할 수 있다.

SIGINT, SIGQUIT등의 문자는 사용이 불가한 건가..?

 

진행함에 앞서 몇가지 실험을 해보자

실행중인 프로세스을 kill하는 예제이다.

 

카운트 다운
kill

위와 같은 결과로 실행중인 프로세스를 kill하는 법을 알아간다.

여기서 우리가 알수 있는 것은 하나의 프로세스에 signal을 주는 것은 이렇게 만들수 있다는 것이다.

 

두번째

SIGUSR1과 SIGUSR2를 사용하는 방법이다.

SIGUSR1, SIGUSR2 테스트
SIGUSR1, SIGUSR2의 signal 전달

위의 결과로 나온다.

우리는 SIGUSR1과 SIGUSR2를 이용해서 signal을 줄 수 있는 방법을 알았다.

 

그렇다면 이제 SIGUSR1와 SIGUSR2를 어떤 식으로 사용을 할 수 있을까?

 

그 전에 우리가 한가지 알아야 할 점이 있다.

 

signal과 sigaction은 기능이 비슷하다.

그래서 찾아보면 signal은 핸들러를 구축하는 오래되고 간단한 방법이지만 더이상 사용하지 않는다.

 

그 이유는 무엇이냐!

Unix에서 시그널을 받은 후에 디폴트 값으로 핸들러를 리셋해버리기 때문이다. 만약 죽는 프로세스를 잡기 위해 SIGCHLD 각각을 별도로 핸들링 할 필요가 있는 경우 경쟁이 필요하다. 이 때문에 핸들러 내부에 핸들러를 설정할 필요가 있으며 signal을 호출하기 전에 다른 시그널이 도착할 것이다. 사실 진행중인 프로젝트에는 그렇게 연관성이 있는지 모르겠고 구현이 signal로도 충분히 될 것이라 생각이 든다.

 

하지만, 현재 사용할 수 있는 함수 중 sigaction을 주었기에 사용하여 구현하는 것이 프로젝트가 원하는 바라고 생각이 든다.

 

그래서 우리는 sigaction에 대한 것을 조금 더 깊이 파고들어보자.

 

To Be Continued~

'42일기' 카테고리의 다른 글

python Dict, set 활용  (0) 2021.10.15
Philosophers  (2) 2021.07.09
Push_swap  (0) 2021.06.24
Minitalk(2)  (0) 2021.06.17
Fract-ol  (6) 2021.06.08

+ Recent posts