티스토리 뷰

I/O에 대한 타임아웃 설정하는 방식


1.시스템콜의 인자로 타임을 설정하는 방법

2.sigalram을 사용하는 방법


클라이언트가 connect시스템콜을 호출했는데 서버 기계는 존재하지만 프로세스가 존재하지 않는 경우

서버 커널이 리셋 메세지를 돌려줌.


클라이언트가 connect시스템콜을 호출했는데 서버 기계가 존재하지 않는 경우

타임아웃 발생함.


타임아웃 재전송 타이머는 9분이 넘기 때문에 굉장히 길다.

따라서 connect에 인자로 시간을 설정해서 내가 따로 타임아웃시간을 설정할 수 있다.



SIGALRM 이벤트가 발생했을때 connect_alarm시스템콜을 발생 시키라고 8번줄에서 signal함수로 등록함.

근데 시그널 핸들러가 리턴 될때 프로세스가 시스템콜 호출때문에 블럭 되어 있던 상태라면 그 블럭에서 -1리턴 시키고

errno에 EINTR를 설정한다고 했었다.


이것을 이용해서 클라이언트의 connect 호출이 오랜시간동안 기다리지 않게끔 응용한것이 위의 프로그램이다.


sigfunc 는 시그널 핸들러를 가리키는 함수 포인터이다.

이전에 같은 SIGALRM에 대한 시그널 핸들러로 등록된 프로시져의 시작 주소가 Signal()함수에서 리턴된다.

프로그래밍을 하다 보면 같은 종류에 대한 시그널에 대한 다른 시그널핸들러를 호출하고 싶을때가 있을 것이다.

(타임아웃을 여러개 두고 싶을때 SIGALRM에 대한 시그널 핸들러 다수 존재)


타임아웃을 시그널로 구현하려면 SIGALRM을 발생 시키는 수 밖에 없다.


17번째 줄에서 signal(SIGALRM, sigfunc);을 호출하는데 sigfunc는 예전에 signal함수를 처음 호출했을때 시그널 핸들러의 이름을 리턴한다.

alarm(0) -> 알람을 끄겠다.


nsec는 커넥트의 타임아웃 시간보다 더 적은 시간을 설정해야 의미가 있을 것이다.


하지만 이방법은 좋지 않은 방법이다. 시그널의 사용은 많은 경험이 쌓이지 않은 이상 문제를 발생할 여지가 많으므로

최대한 지양해야 하는 방법이다.


sigfunc = Signal(SIGALRM, connect_alarm);으로 시그널 핸들러를 등록 해 놓고,

밑에서 다시 Signal(SIGALRM,sigfunc); 를 하는 이유


만약에 알람 타이머값이 5,30,50초를 갖는 3개의 알람이 있다고 해보자.

이때 1,2,3번 알람에 맞는 시그널 핸들러가 각각 필요하다. 그런데, 프로세스 수행중에는 1,2,3번 알람중에 어떤것이 먼저 만료될지 알 수 없다.


먼저 SIGALRM에 대해서 핸들러1을 호출할것이라고 Signal()함수로 등록하고 나면 sigfunc에 그 전에 SIGALRM을 처리하던 핸들러2의 시작 주소가 설정 될것이다. 그리고 나서 5초가 지나면 SIGALRM 이 발생해서 핸들러1이 호출되고 처리되고 나면 alarm(0);로 알람을 꺼주고

예전에 등록 되어 있던 SIGALRM핸들러인 핸들러2가 다시 시그널 핸들러로 등록된다.




댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함