리눅스

IO 계열에서 time out 설정하기

macro 2010. 4. 16. 13:20
반응형



* 상황 : 패킷을 받는 역할을 하는 쓰레드에서 recvfrom 함수 사용중, 종료 시그널을 받으면 프로그램을 종료시키기 위해 쓰레드를 종료하기 위함.

* 문제 : 이때 read, readv, recv, recvfrom, recvmsg 등의 함수는 그냥 사용시 block 된다. 따라서 block을 피하기 위한 time out 이 필요함. -> write 계열도 마찬가지.

* 해결 방법
  1. SIGALRM 을 사용하여, read 계열 리턴시 errno == EINTR 인지 확인함. r

  2. read 계열의 함수를 select 로 구현함. UNP v1. p.385 참고.

  3. 소켓 옵션으로 타임아웃을 설정함. read계열 리턴시 errno == EWOULDBLOCK 으로 확인. UNP v1. p.210
     
* 아래는 3번 방법으로 구현한 예.

  - 소켓 생성시 소켓 옵션을 준다.

struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int optlen = sizeof(timeout);
setsockopt(*sock, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, (socklen_t)optlen);
if(bind(*sock, (struct sockaddr*)recv_addr, sizeof(struct sockaddr_in)) == -1) {
   return 2;
}

    -  recv하는 쓰레드에서 errno 로 처리해 준다.
        
       while(1) {
           if(g_exit)
                break;

msg_len = recvfrom(net_check_sock, msg, MAX_MSG_SIZE, 0, (struct sockaddr*)&client_addr, &client_addr_size);     
if(msg_len < 0) {
         if(errno == EWOULDBLOCK){
               printf("EWOULDBLOCK \n");
         continue;
         }
        else {
              printf("[error] recvfrom \n");    
         }
  }
}


 



 


 

반응형