简体   繁体   English

保护主线程免受工作线程中的错误的影响

[英]Protecting main thread from errors in worker thread

When using posix threads, is there some way to "protect" the main thread from errors (such as dereferenced null pointers, division by zero, etc) caused by worker threads. 当使用posix线程时,是否有某种方法可以“保护”主线程免受工作线程引起的错误(例如解除引用的空指针,除零等)。 By "worker thread" I mean a posix thread created by pthread_create(). “工作线程”是指由pthread_create()创建的posix线程。

Unfortunately, we cannot use exceptions - so no "catch", etc. 不幸的是,我们不能使用例外 - 所以没有“捕获”等。

Here is my test program (C++): 这是我的测试程序(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 example above, the error caused by workerThread will terminate the whole program. 在上面的示例中,workerThread引起的错误将终止整个程序。 But I would like the main thread to continue running despite this error. 但我希望主线程继续运行,尽管这个错误。 Is this possible to achieve? 这有可能实现吗?

Sounds to me like you should be using multiple processes, not threads. 听起来像你应该使用多个进程,而不是线程。 Independent processes are automatically protected from these sort of errors happening in other processes. 独立进程会自动受到保护,免受其他进程中发生的这类错误的影响。

You can use pipes or shared memory (or other forms of IPC) to pass data between threads, which has the additional benefit of only sharing the memory you intend to share, so a bug in the worker "thread" cannot stomp on the stack of the main "thread", because it's a separate process with a separate address space. 您可以使用管道或共享内存(或其他形式的IPC)在线程之间传递数据,这样做的另一个好处就是只共享您要共享的内存,因此工作线程中的错误无法踩到堆栈上主“线程”,因为它是一个单独的进程,具有单独的地址空间。

Threads can be useful, but come with several disadvantages, sometimes running in separate processes is more appropriate. 线程可能很有用,但有几个缺点,有时在单独的进程中运行更合适。

The only way I can think of doing this is registering a signal handler, which could instead of aborting the program, cancel the currently running thread, something like this: 我能想到这样做的唯一方法是注册一个信号处理程序,它可以代替中止程序,取消当前运行的线程,如下所示:

void handler(int sig)
{
    pthread_exit(NULL);
}

signal(SIGSEGV, handler);

Note, however, this is unsafe as pthread_exit isn't listed as one of the safe system calls inside a signal handler. 但请注意,这是不安全的,因为pthread_exit未被列为信号处理程序内的安全系统调用之一。 It might work and it might not, depending on the O/S you're running under, and on what signal you're handling. 它可能会起作用,也可能不起作用,这取决于您正在运行的O / S,以及您正在处理的信号。

Assuming your system uses signals in a POSIX sort of a way (though that may fall under the "no exceptions" rule), then POSIX says: 假设您的系统使用POSIX中的信号排序(尽管可能属于“无例外”规则),那么POSIX说:

At the time of generation, a determination shall be made whether the signal has been generated for the process or for a specific thread within the process. 在生成时,应确定是为过程还是为过程中的特定线程生成了信号。 Signals which are generated by some action attributable to a particular thread, such as a hardware fault, shall be generated for the thread that caused the signal to be generated. 应该为导致生成信号的线程生成由可归因于特定线程的某些动作(例如硬件故障)生成的信号。

So you can handle SIGSEGV , SIGFPE , etc. on a per pthread basis (but note that you can only set one signal handler function for the entire process). 因此,您可以在每个pthread的基础上处理SIGSEGVSIGFPE等(但请注意,您只能为整个过程设置一个信号处理函数)。 So, you can "protect" the process from being stopped dead by a failure in a single pthread... up to a point. 因此,您可以“保护”该过程,使其免于因单个pthread失败而停止死亡......直至某一点。 The problem, of course, is that you may find it very difficult to tell what state the process -- the failed pthread, and all the other pthreads -- is in. The failed pthread may be holding a number of mutexes. 当然,问题在于你可能会发现很难分辨出进程的状态 - 失败的pthread和所有其他的pthreads - 失败的pthread可能会持有多个互斥锁。 The failed pthread may be leaving some shared data structure(s) in a mess. 失败的pthread可能会使一些共享数据结构混乱。 Who knows what sort of a tangle things are in -- unless the pthreads are essentially independent. 谁知道什么样的纠结事物 - 除非pthreads基本上是独立的。 It may be possible to arrange for other pthreads to close down "gracefully"... rather than crash and burn. 也许可以安排其他pthreads“优雅地”关闭......而不是崩溃和燃烧。 It may, in the end, be safer to stop all pthreads dead, rather than try to continue in some less than well defined state. 最终,它可能更安全地阻止所有pthreads死亡,而不是试图继续在一些不太明确的状态。 It will depend entirely on the nature of the application. 它完全取决于应用程序的性质。

Nothing is for nothing... threads can communicate with each other more easily than processes, and cost less to start and stop -- processes are less vulnerable to failure of other processes. 没有什么是无用的......线程可以比流程更容易地相互通信,并且启动和停止成本更低 - 流程不易受到其他流程故障的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM