Linux Pthread_kill

pthread_kill:

别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数。

int pthread_kill(pthread_t thread, int sig);

向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。

pthread_kill(threadid, SIGKILL)也一样,杀死整个进程。
如果要获得正确的行为,就需要在线程内实现signal(SIGKILL,sig_handler)了。

所以,如果int sig的参数不是0,那一定要清楚到底要干什么,而且一定要实现线程的信号处理函数,否则,就会影响整个进程。


OK,如果int sig是0呢,这是一个保留信号,一个作用是用来判断线程是不是还活着。

我们来看一下pthread_kill的返回值:
成功:0
线程不存在:ESRCH
信号不合法:EINVAL

所以,pthread_kill(threadid,0)就很有用啦。

int kill_rc = pthread_kill(thread_id,0);

if(kill_rc == ESRCH)
printf("the specified thread did not exists or already quit/n");
else if(kill_rc == EINVAL)
printf("signal is invalid/n");
else
printf("the specified thread is alive/n");

上述的代码就可以判断线程是不是还活着了。

 

 

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://xufish.blogbus.com/logs/40545082.html

使用pthread_kill函数检测一个线程是否还活着的程序,在linux环境下gcc编译通过,现将代码贴在下面:

/******************************* pthread_kill.c *******************************/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

void *func1()/*1秒钟之后退出*/
{
    sleep(1);
    printf("线程1(ID:0x%x)退出。/n",(unsigned int)pthread_self());
    pthread_exit((void *)0);
}

void *func2()/*5秒钟之后退出*/
{
    sleep(5);
    printf("线程2(ID:0x%x)退出。/n",(unsigned int)pthread_self());
    pthread_exit((void *)0);
}

void test_pthread(pthread_t tid) /*pthread_kill的返回值:成功(0) 线程不存在(ESRCH) 信号不合法(EINVAL)*/
{
    int pthread_kill_err;
    pthread_kill_err = pthread_kill(tid,0);

    if(pthread_kill_err == ESRCH)
        printf("ID为0x%x的线程不存在或者已经退出。/n",(unsigned int)tid);
    else if(pthread_kill_err == EINVAL)
        printf("发送信号非法。/n");
    else
        printf("ID为0x%x的线程目前仍然存活。/n",(unsigned int)tid);
}

int main()
{
    int ret;
    pthread_t tid1,tid2;
    
    pthread_create(&tid1,NULL,func1,NULL);
    pthread_create(&tid2,NULL,func2,NULL);
    
    sleep(3);/*创建两个进程3秒钟之后,分别测试一下它们是否还活着*/
    
    test_pthread(tid1);/*测试ID为tid1的线程是否存在*/
    test_pthread(tid2);/*测试ID为tid2的线程是否存在*/

    exit(0);
}


编译:gcc -o pthread_kill -lpthread pthread_kill.c
运行:./pthread_kill

/ 运行结果 /
线程1(ID:0xb7e95b90)退出。
ID为0xb7e95b90的线程不存在或者已经退出。
ID为0xb7694b90的线程目前仍然存活。



pthread_kill(3) - Linux man page


Name

pthread_kill - send a signal to a thread

Synopsis

#include <signal.h>int pthread_kill(pthread_t thread, int sig);
Compile and link with -pthread.

Description

The pthread_kill() function sends the signal sig to thread, another thread in thesame process as the caller. The signal is asynchronously directed to thread.

If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a thread ID.

Return Value

On success, pthread_kill() returns 0; on error, it returns an error number, and no signal is sent.

Errors

EINVAL
An invalid signal was specified.
ESRCH
No thread with the ID thread could be found.

Conforming to

POSIX.1-2001.

Notes

Signal dispositions are process-wide: if a signal handler is installed, the handler will be invoked in thethread thread, but if the disposition of the signal is "stop", "continue", or "terminate", this action will affect the whole process.

See Also

kill(2) sigaction(2), sigpending(2),pthread_self(3),pthread_sigmask(3),raise(3),pthreads(7),signal(7)



====================================================================================================================================

关闭一个线程


注意:由于个人能力及知识水平问题,以下内容可能有原则性错误,请批判着阅读!
最近搜东西,又搜到了这个关于pthread_kill的话题,相信有不少人看过这个讨论。NPTL的作者真霸道。看了几遍pthread_kill的手册,然后放心的写代码,然后得到一个core dump,相信谁都会不爽的。
但用pthread_kill(pid, 0)来检测一个线程的运行情况是一件不靠谱的行为,虽然这是非常普遍的行为:Joinable的线程完结了,还没执行pthread_join(),这个状态,pthread_kill(pid, 0)能正常识别么?规范没有说,其实很多实现都没有能够区分这两种状态吧。(1 运行中, 2 运行结束,还没join)还有一种比较不大可能发生的事情——通常,你的代码能提前发现这个问题:pid如果被重用了呢?这种时候,其实你检查的是一个全新的线程。
pthread_kill()是一个非常难用的方法,在确定你的线程能正确的处理信号之前,不能随意的向某个线程发出信号;如果你的程序不能正确处理,你的整个系统都会由于这个方法的调用而终止。出于对其的害怕,我从来没有在自己的代码里使用过它。
如果要关闭一个Server线程,其实可以为线程提供一个shutdown()方法,像所有Java程序员都会的那样;如果要立刻终止一个线程,可以用pthread_cancel(pthread_t),当然这个方法也会有风险(你不知道你要关闭的线程是不是已经终止了,你也不知道你要关闭的线程或许是一个全新的线程)。所以,pthread_cancel(pthread_t)方法需要在同步块内调用,调用前,确认 线程处于有效的状态。而线程也需要在同步块内才能改变自己的状态。
我觉得安全的做法,不论是pthread_cancel,或是pthread_kill,都需要利用同步机制,确认线程先有效,再操作。当然,很多人不这么认为,因为他们的代码从不这样写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值