2017-02-15 2 views
0

Я написал небольшой тест ppoll, но меня смущает обработка сигнала. Страница человек говорит:Сигналы в ppoll не обрабатываются немедленно

Отношения между опроса() и ppoll() аналогична взаимосвязи между выберите (2) и pselect (2): как pselect (2), ppoll() позволяет приложению безопасно дождитесь, пока либо файловый дескриптор не будет готов, либо пока не будет обнаружен сигнал.

В моем случае изменения fd обрабатываются немедленно, когда сигналы обрабатываются после таймаута. Я использовал ctr-c в контексте процесса и убил из другой оболочки, но всегда имел такое же поведение.

Что я делаю неправильно? Я что-то пропустил?

#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, вы сказали ей, чтобы блокировать SIGINT и SIGTERM, передавая их в маске сигнала.

+0

Большое спасибо. Я слишком много читал эту страницу и не мог решить эту проблему самостоятельно. Имеют смысл, потому что иначе я мог бы просто использовать функцию опроса. – sorth

Смежные вопросы