As chamadas de sistema select (2), poll (2) e epoll (7) são apenas uma maneira de esperar por eventos em descritores de arquivos (inteiros pequenos representando um canal de E / S). Os eventos podem incluir "dados lidos para leitura", "prontos para escrever", coisas desse tipo. Seu código compõe um conjunto de descritores de arquivos que eventualmente terão um evento, e então chama select (), ou poll () ou epoll () para fazer o programa esperar até que os dados cheguem, o kernel conecta o socket a algum outro host , um descritor teve um erro, qualquer que seja.
signalfd (2) adiciona um novo evento: um sinal chegou. Em unix / linux / * BSD, um "sinal" é um evento mais ou menos assíncrono: a CPU tentou executar uma instrução ilegal, a E / S está pronta, o código dividido por zero, o modem desligado. signalfd (2) permite criar um descritor de arquivo, utilizável em select (), poll (), epoll (), que possui um evento quando um sinal chega.
No passado, você especificaria uma função de manipulador, que o kernel chamaria magicamente quando chegasse um sinal (a.k.a. um "upcall"). Se você usou a chamada do sistema sigaction () para dizer ao kernel qual função você queria chamar, você obteve as mesmas informações que o sigwaitinfo () pode obter.
A diferença entre configurar uma função de manipulador com signal () ou sigaction () sobre signalfd () é que a função manipuladora poderia ser chamada magicamente a qualquer momento: partes de seu código tinham que ser reentrantes (não apenas threads seguro, lembre-se de você) para lidar com a natureza dos sinais "a qualquer momento". Com signalfd (), um sinal é apenas outro evento para lidar no loop de eventos do seu código. Seu código é executado como de costume.
sigwaitinfo () faz com que seu código pause até e quando um sinal especificado chegar. Seu código não faz nada até que esse sinal chegue. Nenhum loop de evento, nada. Também parece que o sigwaitinfo () faz parte do material em tempo real no kernel do Linux. O sigwaitinfo () poderia ser considerado como designando um ponto no código para o kernel chamar quando um sinal chega, ao invés de designar uma função para chamar.
Adição:
Acabei de descobrir uma postagem no blog sobre o "truque do autopubamento ". Aparentemente, não só é inconveniente em termos de código para lidar com sinais e E / S baseada em seleção, você também pode sofrer "condições desagradáveis de corrida". O truque do self pipe gira em torno disso, fazendo essencialmente o que signalfd (2) faz, mas tudo no espaço do usuário, e a um custo de mais código.