线程解析(二)

时间:2009-12-22

  作者:曹忠明,华清远见嵌入式学院讲师。

  上次说了如何去创建一个线程及如何向线程中传递一个参数那么这次我们说一下如何终止一个线程。

  如进程中调用exit,_exit使进程结束一样,线程也可以通过类似的方法结束。
        一、线程的执行体结束线程自然结束。
        二、可以通过调用pthread_exit使程序结束。

  pthread_exit 的原型为:
        void pthread_exit(void *value_ptr);
        value_ptr是一个无类型返回值,其他线程可以通过调用phread_join来获得这个值。
        phread_join 的原型为:
        int pthread_join(pthread_t thread, void **value_ptr);

  调用pthread_join可以等待线程thread的退出并获得退出时的状态,如果不关心线程返回值的话,value_ptr可以置为NULL,下面我们用一个例程说明这两个函数的使用方法。
        #include <stdio.h>
        #include <pthread.h>

void *thread_a(void *arg)
        {
                printf("thread 1 enter\n");
                pthread_exit((void *)1);
        }

void *thread_b(void *arg)
        {
                printf("thread 2 enter\n");
                pthread_exit((void *)2);
        }

int main(int argc, char **argv)
        {
                pthread_t tid_a,tid_b;
                int err;
                void *value_ptr;

        err = pthread_create(&tid_a,NULL,thread_a,NULL);
                if(err < 0)
               {
                        perror("pthread_create thread_a");
                }

        err = pthread_create(&tid_b,NULL,thread_b,NULL);
                if(err < 0)
                {
                        perror("pthread_create thread_a");
                }

        pthread_join(tid_b,&value_ptr);
                printf("phtread %d exit!\n",(int)value_ptr);

        pthread_join(tid_a,&value_ptr);
                printf("phtread %d exit!\n",(int)value_ptr);

        sleep(5);
                printf("the main close\n");
                return 0;
        }

  三、被统一线程中的其他线程取消而结束。

  线程可以通过调用pthread_cancel函数向同一进程中的其他线程发送取消的信号,但是这个先好的响应可以设定,可以设置为立即终止或忽略。所以发送取消信号并不意味着线程就会终止。

  与线程取消相关的函数有:
        phtread_cancel原型为:
        int pthread_cancel(pthread_t thread);
        这个函数向线程thread发送终止信号。
        pthread_setcancelstate原型为:
        int pthread_setcancelstate(int state, int *oldstate);

  这个函数设定线程接收到终止信号的反应,state有两种值:PHTREAD_CANCEL_ENABLE(默认为这个状态)和PHREAD_CANCEL_DISABLE,这两个值分别代表接受掉终止信号终止线程和或略这个信号。oldstate用来存放线程原来的状态用来以后恢复只用,如不用回复可以设置为NULL。

pthread_setcanceltype原型为:
        int pthread_setcanceltype(int type, int *oldtype);

  这个函数用来设定线程接收到终止信号的执行时间,type也是有两个值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,这两个值分别表示线程接收到终止信号是运行到下一个取消点退出还是立即退出。同样oldtype也是用来存放线程原来的状态。

pthread_testcancel原型为:
        void pthread_testcancel(void);
        检查线程是否处于canceld状态如果是则执行取消动作否则立即返回。

  下面用一个例程说明这几个函数的使用。
        #include <stdio.h>
        #include <pthread.h>

void *thread_a(void *arg)
        {
                if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL) != 0)
                {
                        perror("setcancelstate");
                }
                if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL) != 0)
                {
                        perror("setcancelsype");
                }
                while(1)
                {
                        sleep(1);
                        printf("thread_a\n");
                        pthread_testcancel();
                }
        }

void *thread_b(void *arg)
        {

        if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL) != 0)
                {
                        perror("setcancelstate");
                }
                while(1)
                {
                        sleep(1);
                        printf("thread_b\n");
                        pthread_testcancel();
                }
        }

void *thread_c(void *arg)
        {
                if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL) != 0)
                {
                        perror("setcancelstate");
        }

        if(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL) != 0)
                {
                        perror("setcancelsype");
                }

        while(1)
                {
                        sleep(1);
                        printf("thread_c\n");
                        pthread_testcancel();
                }
        }

int main(int argc, char **argv)
        {
                pthread_t tid_a,tid_b,tid_c;
                int err;

        err = pthread_create(&tid_a,NULL,thread_a,(void *)&tid_a);
                if(err < 0)
                {
                        perror("pthread_create thread_a");
                }
                printf("create tid_a = %u\n",tid_a);
                err = pthread_create(&tid_b,NULL,thread_b,(void *)&tid_b);
                if(err < 0)
                {
                        perror("pthread_create thread_b");
                }
                printf("create tid_b = %u\n",tid_b);

        err = pthread_create(&tid_c,NULL,thread_c,(void *)&tid_c);
                if(err < 0)
                {
                        perror("pthread_create thread_c");
                }
                printf("create tid_c = %u\n",tid_c);

                sleep(5);
                if(pthread_cancel(tid_a) != 0)
                {
                        perror("pthread_cancel tid_a");
                }

                sleep(5);
                if(pthread_cancel(tid_b) != 0)
                {
                        perror("pthread_cancel tid_b");
                }

        sleep(5);
                if(pthread_cancel(tid_c) != 0)
                {
                        perror("pthread_cancel tid_c");
                }
                sleep(30);
                printf("the main close\n");
                return 0;
        }


  “本文由华清远见https://www.embedu.org/index.htm提供”



  
上一篇:C语言中宏定义和函数的取舍
下一篇:基于Socket的UDP和TCP编程介绍

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料