2017-02-15 64 views
0

我寫了一個小ppoll測試,但我對信號處理感到困惑。該名男子頁說:ppoll中的信號不能立即處理

調查之間的關係()和ppoll()是類似於之間的關係選擇(2)和PSELECT(2):像PSELECT(2),ppoll()允許應用程序安全地等到文件描述符準備就緒或者直到捕獲到信號。

在我的情況下,在超時後處理信號時,會立即處理fd更改。我在進程上下文中使用ctr-c,並從另一個shell中殺死,但始終是相同的行爲。

我在做什麼錯?我錯過了什麼?

#include <iostream> 
#include <poll.h> 
#include <signal.h> 
#include <unistd.h> 

void handleSignal(int signal) 
{ 
    switch(signal) 
    { 
     case SIGINT: 
      std::cerr << "sigint" << std::endl; 
      break; 
     case SIGTERM: 
      std::cerr << "sigterm" << std::endl; 
      break; 
     default: 
      std::cerr << "sig=" << signal << std::endl; 
      break; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    int result; 
    FILE *fd = fopen("/tmp/tmpFile", "r"); 
    result = fileno(fd); 
    if(-1 == result) 
    { 
     std::cerr << "could not open temp file" << std::endl; 
     return EXIT_FAILURE; 
    } 

    pollfd fds[2]; 
    fds[0] = { 0, POLLIN, 0 }; 
    fds[1] = {result, POLLIN, 0 }; 

    sigset_t mySigset, oldSigset; 
    sigemptyset(&mySigset); 
    sigaddset(&mySigset, SIGINT); 
    sigaddset(&mySigset, SIGTERM); 

    struct sigaction mySigHandler; 
    mySigHandler.sa_handler = &handleSignal; 
    mySigHandler.sa_flags = 0; 
    sigemptyset(&mySigHandler.sa_mask); 
    sigaction(SIGINT, &mySigHandler, NULL); 
    sigaction(SIGTERM, &mySigHandler, NULL); 

    char buffer[1024]; 
    timespec time; 
    while(true) 
    { 
     time = {20, 0}; 
     result = ppoll(&fds[0], 2, &time, &mySigset); 
     if(0 == result) 
     { 
      // timeout 
      std::cout << "ppoll timeout" << std::endl; 
     } 
     else if(0 > result) 
     { 
      // error 
      std::cerr << "ppoll error" << std::endl; 
     } 
     else 
     { 
      // at least one fd changed 
      std::cout << "active fds: " << result << std::endl; 

      for(int i = 0; i < 2; i++) 
      { 
       if(fds[i].revents & POLLIN) 
       { 
        result = read(fds[i].fd, buffer, 1024); 
        if (-1 == result) 
        { 
         std::cerr << "error while reading fd " << fds[i].fd << std::endl; 
        } 
        else if(0 < result) 
        { 
         buffer[result] = '\0'; 
         std::cout << "read fd " << fds[i].fd << ": " << buffer << std::endl; 
        } 
       } 
      } 
     } 
    } 
    return EXIT_SUCCESS; 
} 

回答

0

當你叫ppoll,你告訴它通過將其在信號屏蔽來阻止SIGINTSIGTERM

+0

非常感謝。我太多地閱讀手冊頁,並且盲目地自己解決這個問題。有道理,否則我只能使用輪詢功能。 – sorth