我在GNU庫中發現了記錄在SIGU信號中的SIGIO信號。據說只要有輸入(特別是套接字),系統就有可能發送信號。 根據創建此類信號的文檔,我應該將O_ASYNC標誌設置爲相應的filedescritor。 我的問題是,我的GNU版本(GCC 6.3.0)不承認這樣的關鍵字:在GNU中設置標準信號SIGIO
error: ‘O_ASYNC’ undeclared (first use in this function)
我用以下塊設置一個標誌:
/* Set socket status async */
int status = fcntl(sockfd, F_SETFL, O_ASYNC);;
if (status < 0) error("Can't set async mode");
else printf("Async is set for signal %d\n", SIGIO);
我用Cigwin GCC 6.3 0.0
的代碼如下:
static void OnTimer(int sig)
{
/* write request to socket BIO */
}
static void OnTick(int sig)
{
char read[BUFSIZE] = {};
int received;
received = SSL_read(ssl, read, sizeof(read));
/* Handle errors here */
/* print the server's reply */
printf("%s\n\n", read);
}
void connectSSL()
{
/* do all socket set-up and connection */
/* Establish handler for I/O signal */
saction.sa_flags = 0;
saction.sa_handler = OnTick;
sigemptyset(&saction.sa_mask);
sigaddset(&saction.sa_mask, SIGALRM);
if (sigaction(SIGIO, &saction, NULL) == -1) error("sigaction");
else printf("OnTick handler created\n");
/* Set socket status async */
int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | FASYNC);
if (status < 0) error("Can't set async mode");
else printf("Async is set for signal %d\n", SIGIO);
/* Select the process to receive the signal */
int process = fcntl(sockfd, F_SETOWN, getpid());
if (process < 0) error("Can't set address process");
else printf("Process %d is set\n", getpid());
/* do the rest SSL staff here */
}
int main(int argc, char argv[])
{
sigset_t mask, oldmask;
/* Wait for OnTimer event*/
sigemptyset(&oldmask);
sigaddset(&oldmask, SIGALRM);
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
sigaddset(&mask, SIGIO);
sigprocmask(SIG_BLOCK, &mask, &oldmask);
connectSSL();
createTimer(500000000);
while(1)
{
printf("\nWaiting OnTimer %d\n", count + 1);
sigsuspend(&oldmask);
}
return 0;
}
除了下面我實際的回答:在我的經驗信號控制的I/O開闢了更多的問題比它實際上解決。一旦你從一個信號處理程序(你的操作系統查找「異步安全函數」)中知道你實際上可能做了什麼*,你可能想要將你的設計恢復爲'select'。 – tofro
也許你是對的。不過我想嘗試一下。目前我無法設置這個信號。 –
我並不完全滿意select的一個原因是select在socket中有實際輸入消息之前被調用4次。我猜想select會連續輪詢所有I/O描述符,並在所有其他fds準備就緒時回退1。我需要更快的解決方案 –