UNIX/Linux signal handling: SIGEV_THREAD
Solution 1
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. Thesigev_signo
field specifies the signal, thesigev_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. Thesigev_notify_function
field specifies the function that is called,sigev_value
contains supplementary data that is passed to the function, andsigev_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.
Solution 2
I think you are mixing up your signal handling idioms here, you create a sigevent
structure and then do nothing with it and then use signal()
within the signal handler. The following code shows a very simple signal handling routine based on your code; note that I have changed the definition of my_handler
. If you need more sophisticated handling then sigaction()
is probably the system call you need to look into.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
void my_handler(int sig)
{
printf("my_handler caught\n");
signal(sig,my_handler);
}
int main()
{
signal(SIGRTMIN,my_handler);
kill(0,SIGRTMIN); // This should invoke the signal and call the function
while(1) ; // Infinite loop in case the program ends before the signal gets caught!
}
This works under cygwin
on my windows box (no access to a linux box at the minute).
RajSanpui
Around 9+ years experience into development C, C++, and Linux domain. Also understand Core-Java and consider it as a secondary skill. Currently, in addition to the developer responsibilities, i am also serving the role of DevOps engineer.
Updated on June 05, 2022Comments
-
RajSanpui almost 2 years
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 }
-
Fred Foo about 13 yearsBut the OP's not doing anything with the
sigevent
must logically be the problem, so +1. -
RajSanpui about 13 yearsThis methos i am aware of, but i want to use the sigevent and use the SIGEV_THREAD to invoke the function. If you can please help me in that way, it will be great
-
Jackson about 13 yearsFrom a brief trawl through the docs the problem that you've got is that sigevent is about event handling not about signal handling. It sounds like you want to invoke a signal handler in a new thread whenever the SIGRTMIN signal is received by your process while sigevent is used for things like async io (see the aio man pages). You need to look at the docs for signal() and if your OS supports it sigaction() to see what you can do.