关于pthread_kill()行为

时间:2012-02-28 18:21:16

标签: c operating-system pthreads

我对pthread_kill()行为有疑问。

这是我正在尝试的一个小代码:

void my_handler1(int sig)
{
    printf("my_handle1: Got signal %d, tid: %lu\n",sig,pthread_self());
    //exit(0);
}

void *thread_func1(void *arg)
{
    struct sigaction my_action;
    my_action.sa_handler = my_handler1;
    my_action.sa_flags = SA_RESTART;
    sigaction(SIGUSR1, &my_action, NULL);
    printf("thread_func1 exit\n");
}


void *thread_func2(void *arg)
{
    int s;
    s = pthread_kill(tid1_g,SIGUSR1);
    if(s)
            handle_error(s,"tfunc2: pthread_kill");

    printf("thread_func2 exit\n");
}


int main()
{
    int s = 0;
    pthread_t tid1;

    s = pthread_create(&tid1,NULL,thread_func1,NULL);
    if(s)
            handle_error(s,"pthread_create1");

    tid1_g = tid1;
    printf("tid1: %lu\n",tid1);
    s = pthread_join(tid1,NULL);
    if(s)
            handle_error(s, "pthread_join");

    printf("After join tid1\n");

    pthread_t tid3;
    s = pthread_create(&tid3,NULL,thread_func2,NULL);
    if(s)
            handle_error(s,"pthread_create3");

    s = pthread_join(tid3,NULL);
    if(s)
            handle_error(s, "pthread_join3");

    printf("After join tid3\n");
    return 0;
}

我得到的输出是:

tid1: 140269627565824
thread_func1 exit
After join tid1
my_handle1: Got signal 10, tid: 140269627565824
thread_func2 exit
After join tid3

所以,即使我在已经完成的线程上调用pthread_kill(),该线程的处理程序仍然被调用。如果线程不存在,pthread_kill()是否应该返回错误(ESRCH)?

3 个答案:

答案 0 :(得分:7)

线程在其生命周期之后(即在pthread_t成功返回之后,或者在线程终止于分离状态之后)pthread_join的任何使用(*)结果在未定义的行为。如果ESRCH仍然有效,即如果您尚未加入该主题,则应该只期望pthread_t。否则所有投注都会被取消。

注意:通过“use”(*),我的意思是将它传递给标准库中的pthread_函数。据我所知,只是将它分配给另一个pthread_t变量或者在你自己的函数之间传递它而不“使用”它不会导致UB。

答案 1 :(得分:3)

根据这个SO thread说将信号传递给已经死亡的线程(仅当线程被加入或退出时)会导致未定义的行为!

编辑:找到一个thread,它明确引用了最新的POSIX规范,指出了未定义的行为。谢谢R ..正确的指针!

答案 2 :(得分:0)

问题asked here(如何确定pthread是否还活着)已被标记为重复此问题。

但我相信这篇文章只是澄清了pthread_kill的行为,并确认如果使用不再有效的ID调用pthread_kill,它就不能保证正确的行为。因此,pthread_kill不能用于知道线程是否存在,就好像线程先前已经加入一样,ID不会有效或者会被重新使用,如果它已被分离为如果线程被终止,资源可能已被回收。

因此,为了确定线程是否存活(特别询问可连接线程的问题),我只能想到一个解决方案如下:

使用一些全局数据/内存,两个线程都可以访问这些数据/内存,并存储线程的返回/退出状态,这些状态需要在那里确定。其他线程可以检查此数据/ locatin以获取其状态。 (显然这假设线程正常退出,即连接或分离)。

例如:

Have a global bool named as "bTerminated" initialized with "FALSE" and in
the handler function of this thread either make it as "TRUE" before
returning or modify it once it is returned to the caller (i.e where you have
called `pthread_join` for this thread). Check for this variable in any other
threads where you want to know if this thread is alive. Probably it will be
straight to implement such a logic which fits into your original code.