Protecting the main thread from workflow errors

When using posix threads, is there a way to “protect” the main thread from errors (such as dereferenced null pointers, division by zero, etc.) caused by worker threads. By "work thread" I mean the posix thread created by pthread_create ().

Unfortunately, we cannot use exceptions - so "catch", etc.

Here is my test program (C ++):

void* workerThreadFunc(void* threadId) { int* a = NULL; *a = 5; //Error (segmentation fault) pthread_exit(NULL); } int main() { cout << "Main thread start" << endl; pthread_t workerThread; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&workerThread, &attr, workerThreadFunc, (void*)0); pthread_join(workerThread, NULL); cout << "Main thread end" << endl; } 

In the above example, the error caused by workThread will terminate the entire program. But I would like the main thread to continue to work, despite this error. Can this be achieved?

+6
source share
3 answers

It sounds as if you should use multiple processes, not threads. Independent processes are automatically protected from similar errors occurring in other processes.

You can use channels or shared memory (or other forms of IPC) to transfer data between streams, which has an additional advantage only for exchanging the memory that you are going to share, so an error in the worker "stream" cannot stomp the stack of the main "stream", because that it is a separate process with a separate address space.

Themes may be useful, but come with several flaws, sometimes more suitable for individual processes.

+8
source

The only way I can do this is to register a signal handler that, instead of interrupting the program, could cancel the current current thread, something like this:

 void handler(int sig) { pthread_exit(NULL); } signal(SIGSEGV, handler); 

Please note that this is unsafe since pthread_exit not displayed as one of the safe system calls inside the signal handler. It may work, and it may not be so, depending on the O / S you are using and on what signal you are processing.

+5
source

Assuming your system uses signals in the form of POSIX (although this may fall under the “no exception” rule), then POSIX says:

During generation, it must be determined whether a signal is generated for the process or for a particular thread in the process. Signals that are generated by some action associated with a particular thread, such as a hardware error, must be generated for the thread that caused the signal to be generated.

This way you can handle SIGSEGV , SIGFPE , etc. based on pthread (but note that you can only set one signal handler function for the whole process). That way you can “protect” the process from stopping the dead crash in one pthread ... to the point. The problem, of course, is that it can be very difficult for you to say what state the process is in - failed pthread and all other pthreads. As a result of unsuccessful pthread, there may be several mutexes. Bad pthread can leave some common data structures in a mess. Who knows what things are in the club, unless pthreads are essentially independent. Perhaps you can arrange other pthreads to close "gracefully" ... instead of burning and burning. In the end, it may be safer to stop all pthreads dead, rather than trying to continue in some less clearly defined state. This will depend entirely on the nature of the application.

Nothing is anything ... threads can communicate with each other more easily than processes, and cost less to start and stop - processes are less vulnerable to other processes failing.

+4
source

Source: https://habr.com/ru/post/975639/


All Articles