本文介绍了信号处理程序中的 pthread_exit 导致分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的程序为整个进程设置 SIG_ALRM 处理程序,创建一个线程,将 SIG_ALRM 信号发送到新创建的线程.在 SIG_ALRM 处理程序中调用 pthread_exit.结果 - 分段错误.如果你在发送信号前睡觉 - 好的.

The program below sets SIG_ALRM handler for the whole process, creates a thread, sends SIG_ALRM signal to new created thread.In SIG_ALRM handler pthread_exit is called.The result - segmentation fault.If you sleep before sending signal - OK.

看起来在 pthread_exit 时刻新线程还没有启动.我尝试使用 gdb 定位分段错误,但无法使用 gdb 重现崩溃.

It looks like new thread has not been started at the moment of pthread_exit.I tried to locate segmentation fault with gdb but couldn't reproduce the crash with gdb.

导致分段错误的原因是什么?

What causes segmentation fault?

谢谢!

#include <signal.h>
#include <pthread.h>
#include <iostream>
#include <cassert>
using namespace std;

void* threadFunc(void* arg) {
    cout << "thread: started. sleeping..: " << pthread_self() << endl;
    sleep(10);
    cout << "thread: exit" << endl;
    return NULL;
}

void alrm_handler(int signo) {
    cout << "alrm_handler: " << pthread_self() << endl;

    pthread_exit(NULL); //if comment - no segmentation fault
}

int main() {
    cout << "main: " << pthread_self() << endl;

    struct sigaction act;
    act.sa_handler = alrm_handler;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGALRM, &act, NULL);

    pthread_t t;
    int rc = pthread_create(&t, NULL, threadFunc, NULL);
    assert(rc == 0);

//  usleep(1000); //if Uncomment - no segmentation fault
    rc = pthread_kill(t, SIGALRM);
    assert(rc == 0);

    pthread_join(t, NULL);

    cout << "main: exit" << endl;
    return 0;
}

输出:

主:140130531731232
警报处理程序:140130504095488
分段错误

推荐答案

为要完成的线程初始化过程提供更改.所以只需取消注释以下行是正确的方法.

Give change for thread initialization process to be completed. so just uncomment the below line is the right approach.

  usleep(1000);

这篇关于信号处理程序中的 pthread_exit 导致分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-16 00:44