Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15995
  • 博文数量: 6
  • 博客积分: 130
  • 博客等级: 入伍新兵
  • 技术积分: 70
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-08 00:17
文章分类

全部博文(6)

文章存档

2008年(6)

我的朋友
最近访客

分类: LINUX

2008-08-08 00:49:38

2008-08-07 20:03 线程_终止


线程的终止有三种形式:

  • 线程从线程函数中执行完代码,返回。
  • 线程被同一进程中其他线程取消。
  • 线程调用pthread_exit。

  1. void pthread_exit(void* rval_ptr); 中rval_ptr可以被pthread_join获取,以获得线程的退出状态。需要注意的是rval_ptr这个参数必须在调用时是有效的,即其不能随线程的exit而变得无效。
  2. 线程被同一进程其他线程取消, 例:cancel_thread.c
    • 在线程中设置允许取消(默认是允许取消的)。pthread_setcancelstate(int state, int* oldstate); state是“可取消状态”值为:PTHREAD_CANCEL_ENABLE和PTHREAD_CANCEL_DISABLE,oldstate存储设置之前线程的“可取消状态”。
    • 取消可分延时取消(默认)和异步取消,异步取消时线程可随时取消,延时取消时线程在“取消点”可被取消。设置取消类型函数:pthread_setcanceltype(int type, int* oldtype); type是取消类型, 值为:PTHREAD_CANCEL_DEFERRED(延时取消)和PTHREAD_CANCEL_ASYNCHRONOUS(异步取消);oldtype存储设置之前线程的取消类型。
    • 取消点:是线程检查是否被取消并按照请求进行动作的一个位置。在延迟取消时,线程在取消请求发出后继续运行,直到线程到达某个取消点。POSIX.1取消点定义(UNIX环境高级编程:P332 表12-7,P333 表12-8)。可以自己添加取消点:void pthread_testcancel(void),使用见例子。
  3. 线程退出时的消除动作:线程清理处理程序。需要在线程开始时进行注册,在线程退出时以“逆序”执行(因为是放在栈里面)。例:clean_up_thread.c
  • 注册:pthread_cleanup_pop(void (*rtn)(void *), void *arg),rtn清理函数名,arg需要传入的参数
  • 清理:pthread_cleanup_push(int execute),execute是否执行,0:不执行,其他:执行
  • 清理的三个开始点:调用pthread_exit时;响应取消请求时;用非0调用 pthread_cleanup_push时。
code:

/** cancel_thread.c */
/** debian 下编译通过 */
#include
#include
#include
#include

void* thr_fn1(void* arg)
{
    /** 设置线程可被取消, 默认 */
    //pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    /** 设置线程不可被取消 */
    //pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
   
    /** 设置线程延迟取消, 默认*/
    //pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
   
    /** 设置线程异步取消*/
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
    while(1) {
        //; //在延迟取消时,无法取消
        printf("thead 1 running\n"); //系统定义取消点
        //sleep(1);    //系统定义取消点
        //pthread_testcancel(); //设置自己的取消点
    }
    printf("thead 1 exit\n");
    return (void *)0;
}

int main(int argc, char** argv)
{
    pthread_t tid1;
    int err, *ret;
    char cmd;

    err = pthread_create(&tid1, NULL, thr_fn1, NULL);
    if (err != 0) {
        printf("can't create thread 1: %s", strerror(err));
        return 1;
    }
   
    scanf("%c", &cmd);
    while(cmd != 'q') {
        if (cmd == 'k') {
            err = pthread_cancel(tid1);
            if (err != 0) {
                printf("cancel thread error: %s\n", strerror(err));
                return 1;
            }
           
            err = pthread_join(tid1, (void *)&ret);
            if (err != 0) {
                printf("thread join error: %s\n", strerror(err));
                return 1;
            }
            printf("thread 1 return: %d\n", ret);
            return 0;
        }
        scanf("%c", &cmd);
    }
    return 0;
}


/** clean_up_thread.c */

#include

#include

#include

void clean_up(void *arg)

{

printf("clean up: %s\n", (char *)arg);

}

void* thr_fn1(void *arg)

{

pthread_cleanup_push(clean_up, "thread 1 first cleanup progress");

pthread_cleanup_push(clean_up, "thread 1 second cleanup progress"); //用宏实现, 包含“{”, 后面要调用同样数量的pop,否则编译出错

printf("thread 1 push complete\n");

if (arg)

return ((void *)1); //返回终止,不会调用clean up

pthread_cleanup_pop(0); //与pthread_clean_push的个数相对应,因为是用宏实现,包含“}”

pthread_cleanup_pop(0);

return ((void *)1);

}

void* thr_fn2(void *arg)

{

pthread_cleanup_push(clean_up, "thread 2 first cleanup progress");

pthread_cleanup_push(clean_up, "thread 2 second cleanup progress");

printf("thread 2 push complete\n");

if (arg)

pthread_exit((void *)2); //pthread_exit终止,调用clean up

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

pthread_exit((void *)2);

}

void* thr_fn3(void *arg)

{

pthread_cleanup_push(clean_up, "thread 3 first cleanup progress");

pthread_cleanup_push(clean_up, "thread 3 second cleanup progress");

printf("thread 3 push complete\n");

while(1) {

pthread_testcancel(); //外部终止,调用clean up

}

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

return ((void *)1);

}

int main(int argc, char **argv)

{

int err;

pthread_t tid1, tid2, tid3;

void *tret;

err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);

if (err != 0) {

printf("can't create thread 1: %s\n", strerror(err));

return 1;

}

err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);

if (err != 0) {

printf("can't create thread 2: %s\n", strerror(err));

return 1;

}

err = pthread_create(&tid3, NULL, thr_fn3, (void *)1);

if (err != 0) {

printf("can't create thread 3: %s\n", strerror(err));

return 1;

}

err = pthread_join(tid1, &tret);

if (err != 0) {

printf("can't join thread 1: %s\n", strerror(err));

return 1;

}

printf("thread 1 exit code: %d\n", (int)tret);

err = pthread_join(tid2, &tret);

if (err != 0) {

printf("can't join thread 2: %s\n", strerror(err));

return 1;

}

printf("thread 2 exit code: %d\n", (int)tret);

err = pthread_cancel(tid3);

if (err != 0) {

printf("can't cancel thread 3: %s\n", strerror(err));

return 1;

}

err = pthread_join(tid3, &tret);

if (err != 0) {

printf("can't join thread 2: %s\n", strerror(err));

return 1;

}

printf("thread 3 exit code: %d\n", (int)tret);

return 0;

}

阅读(1341) | 评论(0) | 转发(0) |
0

上一篇:线程:sleep和select测试

下一篇:线程:终止

给主人留下些什么吧!~~