2011-03-09 19 views
0

我實現一個客戶端和服務器使用的sendto()和recvfrom()在UDP通信。我想在從服務器接收數據時使用SIGPOLL作爲我的客戶端。我的問題是,在處理程序中,另一個信號到達並丟失。我讀過有一個內核變量(一個標誌),它可以在退出處理程序之前檢查,但我似乎無法找出哪個標誌。SIGPOLL(SIGIO)問題:中斷在執行處理程序

void my_receive_server_data(int sig_num) 
{ 
    /* execute recvfrom() */ 
} 

而且在主:

setup_action.sa_handler = my_receive_server_data; 
    if (sigaction(SIGPOLL, &setup_action, NULL) == -1) 
      perror("Sigaction"); 

    if (fcntl(sock, F_SETOWN, getpid()) < 0) { 
      perror("fcntl"); 
    } 
    if (fcntl(sock, F_SETFL, O_RDONLY | FASYNC) < 0) { 
      perror("fcntl"); 
    } 

目前,如果我不SENDTO後放一個sleep()()在服務器上,只有第一的sendto()獲取客戶端執行(以處理程序,作爲recvfrom())。把睡眠()解決了問題,所以我高度相信這是因爲處理程序只運行一次(因爲它正在執行my_receive_server_data時獲取數據)。

我想請知道什麼旗,我應該從my_receive_server_data返回檢查,而處理程序執行,請任意輸入已經來臨之前檢查。

非常感謝。

+3

爲什麼要使用SIGPOLL?我認爲普遍認爲這是一個非常糟糕的設計,尤其是因爲大多數函數不能從信號處理程序中調用,並且由於需要它們的遺留應用程序,SIGPOLL及其接口僅保留在POSIX中。你應該學會使用'select'或'poll'並編寫一個合適的網絡應用程序。 – 2011-03-09 23:20:49

回答

1

以您嘗試的方式創建穩固的系統非常困難。學習使用阻塞呼叫模型,並使用select()poll()進行I/O多路複用。

如果你打算使用信號不管是什麼,嘗試在信號處理,以減少代碼到最低限度 - 也許只是發送一個字節下來管喚醒一個沉睡的線程或進程,或什麼的。

+0

非常感謝,我理解你的解釋,看起來不錯,但不幸的是,我不得不使用SIGPOLL(選擇不是我的)。我仍然需要知道國旗。 – Jary 2011-03-10 03:03:58

1

該標誌是SA_NODEFER通過限定處理程序SIGPOLL時針對sigaction。