11、线程等待与清除

 

                            线程等待

              #include<pthread.h>

              int pthread_join (pthread_t tid , void **rval_ptr)

              功能:

                     阻塞调用线程,直到指定的线程终止

                     1)Tid:等待退出的线程ID

                     2)Rval_ptr 线程退出的返回值的指针

 

                     例题1.thread_join.c

#include <pthread.h>

#include <unistd.h>

#include <stdio.h>

void *thread(void *str)

{

    int i;

    for (i = 0; i < 3; ++i)

    {

        sleep(1);

        printf( "This in the thread : %d\n" , i );

    }

    return NULL;

}

 

int main()

{

    pthread_t pth;

    int i;

    int ret = pthread_create(&pth, NULL, thread, (void *)(i));

    

    pthread_join(pth, NULL);     //注意与下面的例题区别

    printf("123\n");

    for (i = 0; i < 3; ++i)

    {

        sleep(1);

        printf( "This in the main : %d\n" , i );

    }

   

    return 0;

}

注意:先调用指定的线程,然后进入进程。

 

例题2.thread_join.c

#include <pthread.h>

#include <unistd.h>

#include <stdio.h>

void *thread(void *str)

{

    int i;

    for (i = 0; i < 3; ++i)

    {

        sleep(1);

        printf( "This in the thread : %d\n" , i );

    }

    return NULL;

}

 

int main()

{

    pthread_t pth;

    int i;

    int ret = pthread_create(&pth, NULL, thread, (void *)(i));

   

   // pthread_join(pth, NULL); // 没有了这一句,看打印结果

    printf("123\n");

    for (i = 0; i < 3; ++i)

    {

        sleep(1);

        printf( "This in the main : %d\n" , i );

    }

   

    return 0;

}

总结:

1、     进程创建了线程之后,首先运行的是进程

2、     pthread_join(pth, NULL);让进程等待,去执行指定的线程,直到线程的结束,然后执行进程。

3、     本例中进程与线程都sleep(1)秒,所以当进程运行到sleep(1)时,停止一秒的瞬间,程序到线程执行,线程sleep(1)秒,程序又到进程执行,如此循 环。

 

 

线程标识

           #include<pthread.h>

              pthread_t pthread_self(void)

              功能:

                     获取调用线程的thread identifier

 

 

 

 

 

     例题3.thread_id.c

#include <stdio.h>

#include <pthread.h>

#include <unistd.h> /*getpid()*/

 

void *create(void *arg)

{

    printf("New thread .... \n");

    printf("This thread's id is %u  \n", (unsigned int)pthread_self());

    printf("The process pid is %d  \n",getpid());

    return (void *)0;

}

 

int main(int argc,char *argv[])

{

    pthread_t tid;

    int error;

 

    printf("Main thread is starting ... \n");

 

    error = pthread_create(&tid, NULL, create, NULL);

 

    if(error)

    {

        printf("thread is not created ... \n");

        return -1;

    }

    printf("The main process's pid is %d  \n",getpid());

    sleep(1);  //进程睡眠1秒,程序进入线程

    return 0;

}

            清除

        线程终止有两种情况:

       正常与非正常终止:

Ø        线程主动调用pthread_exit或者从线程函数中return都将使线程正常退出,这是可预见的退出方式。

Ø        非正常终止是线程在其他线程的干预下,或者由于自身运行出错(比如访问非法地址)而退出,这种退出方式是不可遇见的。

 

       从pthread_cleanup_push的调用点到pthread_cleanup_pop之间的程序段中的终止动作(包括调用pthread_exit()和异常终止,不包括return)都将执行pthread_cleanup_push()所指定的清理函数。

           注意:

              pthread_cleanup_push和pthread_cleanup_pop成对出现

 

       #include<pthread.h>

       Void pthread_cleanup_push (void (*rtn)(void*),void *arg)

       功能:

           将清除函数压入清除栈

           Rtn:清除函数

           Arg:清除函数的参数

 

       #include<pthread.h>

       Void pthread_cleanup_pop (int execute)

       功能:

           将清除函数弹出栈

       参数:

           Execute执行到pthread_cleanup_pop ()时是否在弹出清理函数的同时执行该函数,非0,执行。0,不执行

 

 

 

              例题4. thread_clean.c

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

void *clean(void *arg)

{

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

    return (void *)0;

}

void *thr_fn1(void *arg)

{

    printf("thread 1 start  \n");

    pthread_cleanup_push( (void*)clean,"thread 1 first handler");

    pthread_cleanup_push( (void*)clean,"thread 1 second hadler");

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

    if(arg)

    {

        return((void *)1);  //return()特例,不调用pthread_cleanup_push()

    }

    pthread_cleanup_pop(0);

    pthread_cleanup_pop(0);

    return (void *)1;

}

void *thr_fn2(void *arg)

{

    printf("thread 2 start  \n");

    pthread_cleanup_push( (void*)clean,"thread 2 first handler");

    pthread_cleanup_push( (void*)clean,"thread 2 second handler");

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

    if(arg)

    {

        pthread_exit((void *)2);   //提示pthread_cleanup_push()开始工作

    }

    pthread_cleanup_pop(0);

    pthread_cleanup_pop(0);

    pthread_exit((void *)2);

}

int main(void)

{

    int err;

    pthread_t tid1,tid2;

    void *tret;

 

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

    if(err!=0)

    {

        printf("error .... \n");

        return -1;

    }

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

 

    if(err!=0)

    {

        printf("error .... \n");

        return -1;

    }

    err=pthread_join(tid1,&tret);

    if(err!=0)

    {

        printf("error .... \n");

        return -1;

    }

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

 

    err=pthread_join(tid2,&tret);

    if(err!=0)

    {

        printf("error .... ");

        return -1;

    }

 

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

   

    return 1;

}

 

 

        运行

       分析:

       1)void *thr_fn1(void *arg)调用了return()。所以不调用  pthread_cleanup_push()与pthread_cleanup_pop();

       2)void *thr_fn2(void *arg)调用了pthread_exit((void *)2);,所以pthread_cleanup_push()与pthread_cleanup_pop();开始工作。

            为什么会先打印

       因为程序运行到pthread_cleanup_push( (void*)clean,"thread 2 first handler");时,pthread_cleanup_push( (void*)clean,"thread 2 first handler");先进栈,接着pthread_cleanup_push( (void*)clean,"thread 2 second handler");后进栈,打印时pthread_cleanup_push( (void*)clean,"thread 2 second handler");先出栈,所以先打印

若:

其他不变。

     打印:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值