使用信号处理程序处理从fifo收到的数据

问题描述:

我正在用fifo写一个简单的客户机/服务器通信,但我坚持使用信号处理程序来处理客户机请求。使用信号处理程序处理从fifo收到的数据

服务器以只读和非阻塞模式打开fifo,读取收到的数据并将某些数据写回客户端fifo。

而当服务器端没有信号处理程序时,这实际上工作正常。这是双方的主要代码。

服务器:

int main(int argc, char *argv[]) 
{ 
    // install handler 
    struct sigaction action; 

    action.sa_handler = requestHandler; 

    sigemptyset(&(action.sa_mask)); 

    action.sa_flags = SA_RESETHAND | SA_RESTART; 

    sigaction(SIGIO, &action, NULL); 

    if(!makeFifo(FIFO_READ, 0644)) 
     exit(1); 

    int rd_fifo = openFifo(FIFO_READ, O_RDONLY | O_NONBLOCK); // non blocking 

    if(rd_fifo == -1) 
     exit(1); 

    // wait for request and answer 
    while (1) { 
     qWarning() << "waiting client..."; 
     sleep(1); 
     QString msg = readFifo(rd_fifo); 

     qWarning() << "msg = " << msg; 

     if(msg == "ReqMode") { 
      int wr_fifo = openFifo(FIFO_WRITE, O_WRONLY); // blocking 
      writeFifo(wr_fifo, QString("mode")); 
      break; 
     } else 
      qWarning() << "unknow request .."; 
    } 

    close(rd_fifo); 
    unlink(FIFO_READ); 

    return 0; 
} 

客户:

int main(int argc, char *argv[]) 
{ 
    int wr_fifo = openFifo(FIFO_WRITE, O_WRONLY); 

    if(wr_fifo == -1) 
     exit(1); 

    // create a fifo to read server answer 
    if(!makeFifo(FIFO_READ, 0644)) 
     exit(1); 

    // ask the server his mode 
    writeFifo(wr_fifo, QString("ReqMode")); 

    // read his answer and print it 
    int rd_fifo = openFifo(FIFO_READ, O_RDONLY); // blocking 
    qWarning() << "server is in mode : " << readFifo(rd_fifo); 

    close(rd_fifo); 
    unlink(FIFO_READ); 

    return 0; 
} 

一切正常(即使所有的错误都处理不好,这只是一个示例代码,以证明这是可能的)。

问题在于,当客户端向fifo写入数据时,处理程序(此处未显示,但仅在接收到信号时在终端上打印消息)永远不会调用。除此之外,我还检查如果我从bash(或其他地方)发送kill -SIGIO到服务器,信号处理程序将被执行。

感谢您的帮助。

其实,我错过了在服务器端的3个以下行:

fcntl(rd_fifo, F_SETOWN, getpid()); // set PID of the receiving process 

fcntl(rd_fifo, F_SETFL, fcntl(rd_fifo, F_GETFL) | O_ASYNC); // enable asynchronous beahviour 

fcntl(rd_fifo, F_SETSIG, SIGIO); // set the signal that is sent when the kernel tell us that there is a read/write on the fifo. 

最后一点很重要,因为默认的信号发送我的情况是0,所以我不得不明确地将其设置为将SIGIO使事情有效。这里是服务器端的输出:

waiting client... 
nb_read = 0 
msg = "" 
unknow request .. 
waiting client... 
signal 29 
SIGPOLL 
nb_read = 7 
msg = "ReqMode" 

现在,我想这是可能的,以处理移动什么是while循环进入requestHandler函数内部的处理程序中的请求。