登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[pthread] thread cancel  

2009-12-29 21:23:05|  分类: pthread |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
线程A中调用 pthread_cancel(pid_b) 可以让线程pid_b尝试退出。而 pid_b 何时会真正退出,则取决于它的 cancel state & type。函数 pthread_setcancelstate, pthread_setcanceltype 可以用于设置此 state & type,注意,这两个函数相设置当前线程(calling thread)的。

cancel state
PTHREAD_CANCEL_ENABLE, 受 pthread_cancel 影响。
PTHREAD_CANCEL_DISABLE, 不受 pthread_cancel 影响,不退出。

cancel type
只有当 state == ENABLE 时,type 才会起作用。
PTHREAD_CANCEL_DEFERRED, 只有当"被退出的线程(thread being cancel)"碰到一些 cancel point 时,才退出。
PTHREAD_CANCEL_ASYNCHRONOUS, pthread_cancel 一调用,"被退出的线程"立即退出。

cancel point
退出点,一些系统调用都是 cancel point,比如:close(), sleep() 等等。具体可以系统的查询 man page。
我们也可以用 pthread_testcancel(), 自定义 cancel point。

每个线程创建时,默认是 ENABLE, DEFERRED

线程的退出策略,要依据具体的情况而定。我一般都是给线程发送退出指令,让其主动退出,而不使用上面说的 thread cancel 策略。

-------------------------------------
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>

void *mythr_nocancel(void *_)
{
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        printf("mythr_nocancel before sleep, %d\n", time(NULL));
        sleep(3);
        printf("mythr_nocancel after sleep, %d\n", time(NULL));
        return (void *)0;
}

void *mythr_defercancel(void *_)
{
        time_t beg, end;

        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

        // busy run for 5 sec
        beg = time(NULL);
        printf("mythr_defercancel before busy, %d\n", beg);
        do {
                end = time(NULL);
        } while ( end - beg < 5 );      // busy 5 sec
        printf("mythr_defercancel after busy, %d\n", time(NULL));

        // sleep 5 sec (cancel point)
        printf("mythr_defercancel before sleep, %d\n", time(NULL));
        sleep(5);
        printf("mythr_defercancel after sleep, %d\n", time(NULL));

        return (void *)0;
}

void *mythr_asynccancel(void *_)
{
        time_t beg, end;

        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

        beg = time(NULL);
        printf("mythr_asynccancel before busy, %d\n", beg);
        do {
                end = time(NULL);
        } while ( end - beg < 5 );      // busy 5 sec
        printf("mythr_asynccancel after busy, %d\n", time(NULL));
        return (void *)0;
}

void *mythr_testcancel(void *_)
{
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
        printf("mythr_testcancel enter, %d\n", time(NULL));
        while (1) pthread_testcancel();
        printf("mythr_testcancel leave, %d\n", time(NULL));
        return (void *)0;
}

int main()
{
        pthread_t pid;

        pthread_create(&pid, NULL, mythr_nocancel, NULL);
        sleep(1);
        pthread_cancel(pid);
        pthread_join(pid, NULL);

        pthread_create(&pid, NULL, mythr_defercancel, NULL);
        sleep(1);
        pthread_cancel(pid);
        pthread_join(pid, NULL);

        pthread_create(&pid, NULL, mythr_asynccancel, NULL);
        sleep(1);
        pthread_cancel(pid);
        pthread_join(pid, NULL);

        pthread_create(&pid, NULL, mythr_testcancel, NULL);
        sleep(2);
        pthread_cancel(pid);
        pthread_join(pid, NULL);

        return 0;
}
-------------------------------------
$ ./a.out
mythr_nocancel before sleep, 1262092394
mythr_nocancel after sleep, 1262092397
mythr_defercancel before busy, 1262092397
mythr_defercancel after busy, 1262092402
mythr_defercancel before sleep, 1262092402
mythr_asynccancel before busy, 1262092402
mythr_testcancel enter, 1262092403
-------------------------------------
  评论这张
 
阅读(2530)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018