Signals, threads and the use of SIGUSR1

  • Thread starter Gabriele Bartolini
  • Start date
G

Gabriele Bartolini

Hi,

I am writing an application in C++ on Linux, using threads (this is
my first experience with pthreads). The application itself is fine, it
is just that I wanted to handle asynchronous signals correctly, in
particular the SIGINT, preventing the application from stopping
ungracefully.

Indeed, I'd like to catch the signal, close everything in a
consistent way and stop the application.

I ended up structuring the application with a default behaviour of
ignoring any SIGINT, SIGHUP, SIGTERM and SIGUSR1 signals both for the
main process and the 'application threads'. Then I issued a dedicated
thread waiting for one of these signals whose task is to logically stop
the other threads and terminate.

When I press CTRL-C for instance, the thread catches the signal and
stops all the other threads. But, when no event is generated, the risk
is that the thread would be waiting for ever; that's why, when the
application normally finish without an asynchronous signal, I send a
'SIGUSR1' to the thread above and the application normally ends.

I want to know if I am improperly using the SIGUSR1 signal and if -
in this case - there are other ways of accomplishing this.

Thank you very much,
-Gabriele
 
D

David Schwartz

I ended up structuring the application with a default behaviour of
ignoring any SIGINT, SIGHUP, SIGTERM and SIGUSR1 signals both for the
main process and the 'application threads'. Then I issued a dedicated
thread waiting for one of these signals whose task is to logically stop
the other threads and terminate.

This is all quite reasonable.
When I press CTRL-C for instance, the thread catches the signal and
stops all the other threads. But, when no event is generated, the risk
is that the thread would be waiting for ever; that's why, when the
application normally finish without an asynchronous signal, I send a
'SIGUSR1' to the thread above and the application normally ends.

You don't necessarily need to kill the thread. You don't have to
terminate all your threads before the application terminates. Otherwise, you
can use a global variable protected by a mutex to indicate that a clean
shutdown is in progress and code the signal catcher to check that flag
before it does anything else. Then you could send that thread any signal.
However there's nothing wrong with using SIGUSR1 for that purpose.

DS
 
L

Loic Domaigne

Hello Gabriele,
I am writing an application in C++ on Linux, using threads (this is
my first experience with pthreads).

I ended up structuring the application with a default behaviour of
ignoring any SIGINT, SIGHUP, SIGTERM and SIGUSR1 signals both for the
main process and the 'application threads'. Then I issued a dedicated
thread waiting for one of these signals whose task is to logically stop
the other threads and terminate.

Looks good.
When I press CTRL-C for instance, the thread catches the signal and
stops all the other threads. But, when no event is generated, the risk
is that the thread would be waiting for ever; that's why, when the
application normally finish without an asynchronous signal, I send a
'SIGUSR1' to the thread above and the application normally ends.

I want to know if I am improperly using the SIGUSR1 signal and if -
in this case - there are other ways of accomplishing this.


Well, I don't know what kind of actions your "signal handler" thread
- the one that is waiting in sigwait() - does exactly, but I guess,
that's OK to just terminate your process as usual, without explicitely
terminate that thread. When the main thread returns, or one of your threads
terminate the process, then your signal handler thread shall be
automatically terminated.

Only when you need some "clean-up" actions (e.g. be sure that the
destructor of some objects is called etc.) in the signal handler thread
upon the normal process ending, then yes, you need to gracefully terminate
that thread.

Using SIGUSR1 is OK with the 'recent' Pthreads lib (I meant younger
than 2 years old). Indeed, older LinuxThreads library used SIGUSR1 and
SIGUSR2 for internal communications, so you weren't able to use that
signal in your application.

As noted by another poster, if you need to do some clean-up in the
signal thread, you could alternatively used pthread_cancel(). Uses
a deferred cancelation only at sigwait() since that function is a
cancellation point. But using SIGUSR1 is also fine.

Regards,
Loic.
 
P

Peter Zijlstra

Hi,

I am writing an application in C++ on Linux, using threads (this is
my first experience with pthreads). The application itself is fine, it
is just that I wanted to handle asynchronous signals correctly, in
particular the SIGINT, preventing the application from stopping
ungracefully.

Indeed, I'd like to catch the signal, close everything in a
consistent way and stop the application.

I ended up structuring the application with a default behaviour of
ignoring any SIGINT, SIGHUP, SIGTERM and SIGUSR1 signals both for the
main process and the 'application threads'. Then I issued a dedicated
thread waiting for one of these signals whose task is to logically stop
the other threads and terminate.

When I press CTRL-C for instance, the thread catches the signal and
stops all the other threads. But, when no event is generated, the risk
is that the thread would be waiting for ever; that's why, when the
application normally finish without an asynchronous signal, I send a
'SIGUSR1' to the thread above and the application normally ends.

I want to know if I am improperly using the SIGUSR1 signal and if -
in this case - there are other ways of accomplishing this.

Thank you very much,
-Gabriele

Hi,

unless you are using the very new nptl thread implementation on a 2.6
kernel (or a heavily patched 2.4) signals are not handled according to the
posix std.; ie. having a signal handling thread does not work because
signals are delivered to specific threads. There is no de-coupling between
the Thread-ID and the Process-ID; hence new threads have a different
Process-ID.

just my 2 ct.

Have fun coding.

Peter Zijlstra
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top