Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrupting two blocking pthreads by signals

In my application the main thread creates two joined threads; one which waits for user input by calling scanf() in a loop and another one which listens for incoming socket connections by calling accept() in a loop. New connections are handled in separate threads which are detached.

I want the program to shut itself down gracefully when a SIGINT signal is received. That means that the listening thread should stop accepting new connections, wait for threads currently serving connections to close and then then. The thread waiting for user input should also end and thereby allowing the main thread to end.

Scanf() and accept() both block but can be interrupted by a signal, however signals sent to the process can only be handled by one thread (AFAIK). My idea is to block SIGINT signals in all threads except the main thread which will wait for it. When it receives a SIGINT, it will then send SIGUSR1 to the two threads (one which blocks on scanf() and one which blocks on accept()) and then join on these threads.

Is this a good solution? Is there a better or perhaps standard way to achieve this?

like image 545
SlappyTheFish Avatar asked Jan 29 '12 20:01

SlappyTheFish


People also ask

How do I interrupt Pthread?

The pthread_exit() function terminates the calling thread, making its exit status available to any waiting threads. Normally, a thread terminates by returning from the start routine that was specified in the pthread_create() call which started it.

Are signals thread Safe?

It is generally unsafe to provide slots in your QThread subclass, unless you protect the member variables with a mutex. On the other hand, you can safely emit signals from your QThread::run() implementation, because signal emission is thread-safe.

What is pthreads in C?

pthreads or POSIX threads are an implementation of the thread API for C/C++. It allows the spawning of new concurrent process flows and the multithreading system, which allows parallel and distributed processing. It does so by dividing the program into subtasks whose execution can be interleaved to run in parallel.

How to terminate a thread in linux?

If any thread within a process calls exit, _Exit, or _exit, then the entire process terminates.


1 Answers

The canonical solution for problems like this is Thread Cancellation. A cancellation request that arrives while a thread is blocked in a function which is a cancellation point will be acted upon immediately; otherwise, it's acted upon the next time the thread calls a function that's a cancellation point.

The only thing that might be painful about using cancellation is that it's built on a model of exception handling rather than failure returns. You need to either keep cancellation blocked most of the time (and only enable it during operations during which you want to handle cancelling) or else install cancellation cleanup handlers (basically, semi-ugly exception handlers in C) at each call frame level where you might have intermediate state/allocations/etc. to clear out when your thread is cancelled. Personally I prefer the first approach, which generally only requires one cancellation handlers be installed.

Any approach based on interrupting signals inherently has race conditions. If the signal is sent just before the blocking function is called, then when the signal handler returns, the blocking function will be called and will block indefinitely (since the check for "is it time to exit?" was already successfully passed).

like image 61
R.. GitHub STOP HELPING ICE Avatar answered Oct 12 '22 09:10

R.. GitHub STOP HELPING ICE