Search code examples
clinuxunixposixsignals

UNIX/Linux signal handling: SIGEV_THREAD


I have put a simple signal handler in my code. I have initialised the sigevent structure, with a handler function to catch the signal.

Can someone please pin-point as to why the code is not working? Ideally if there is a signal, my handler should be called. But it is not.

Please help me, Thanks Kingsmasher1

enter code here
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

void my_handler(int sival_int, void* sival_ptr)
{
 printf("my_handler caught\n");
 signal(sig,my_handler);
}

int main()
{
 struct sigevent sevp;

 sevp.sigev_notify=SIGEV_THREAD;
 sevp.sigev_signo=SIGRTMIN;
 sevp.sigev_value.sival_ptr=NULL;
 sevp.sigev_notify_function=(void*)my_handler;
 kill(0,SIGRTMIN); // This should invoke the signal and call the function
}

Solution

  • struct sigevent is not about specifying how the process will handle a signal - struct sigaction and sigaction() are how you do that. Instead, struct sigevent is used to specify how your process will be informed of some asychronous event - like the completion of asychronous IO, or a timer expiring.

    The sigev_notify field specifies how the event should be notified:

    • SIGEV_NONE - no notification at all. The remainder of the fields are ignored.
    • SIGEV_SIGNAL - a signal is sent to the process. The sigev_signo field specifies the signal, the sigev_value field contains supplementary data that is passed to the signal handling function, and the remainder of the fields are ignored.
    • SIGEV_THREAD - a function is called in a new thread. The sigev_notify_function field specifies the function that is called, sigev_value contains supplementary data that is passed to the function, and sigev_notify_attributes specifies thread attributes to use for the thread creation. The remainder of the fields are ignored.

    Note in particular that if you set SIGEV_THREAD, the sigev_signo field is ignored - the struct sigevent is about specifying either a thread or a signal as a notification method, not about specifying a thread as the way that a signal should be handled.

    The struct sigevent must also be passed to a function - like timer_create() - that sets up the asychronous event that will be notified. Simply creating a struct sigevent object does not do anything special.

    If you wish to use a dedicated thread to handle a signal, create the thread up front and have it loop around, blocking on sigwaitinfo(). Use sigprocmask() to block the signal in every other thread.