Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
}
like image 758
RajSanpui Avatar asked Mar 01 '11 11:03

RajSanpui


People also ask

What is Sigev_thread?

SIGEV_THREAD Notify the process by invoking sigev_notify_function "as if" it were the start function of a new thread. (Among the implementation possibilities here are that each timer notification could result in the creation of a new thread, or that a single thread is created to receive all notifications.)

How do signal handlers work?

A signal handler is a function which is called by the target environment when the corresponding signal occurs. The target environment suspends execution of the program until the signal handler returns or calls longjmp() . Signal handlers can be set with signal() or sigaction() .

What is signal function in Linux?

signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer- defined function (a "signal handler"). If the signal signum is delivered to the process, then one of the following happens: * If the disposition is set to SIG_IGN, then the signal is ignored.


2 Answers

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.

like image 64
caf Avatar answered Oct 25 '22 06:10

caf


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).

like image 20
Jackson Avatar answered Oct 25 '22 05:10

Jackson