c 线程的取消和终止

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

如进程中调用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

#include

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

#include

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;

}

在C语言中,终止线程一个常见的多线程编程任务,主要依赖于POSIX线程库(`pthread`)。有多种方法可以实现线程终止,每种方法都有其适用场景注意事项。 ### 1. 通过 `pthread_exit()` `pthread_exit()` 函数允许线程主动终止自己的执行,并且可以返回一个值给等待该线程结束的其他线程。这种方式适用于线程需要主动退出并传递结果的情况。例如: ```c #include <stdio.h> #include <pthread.h> void *ThreadFun(void *arg) { // 终止线程的执行,并返回一个字符串 pthread_exit("http://c.biancheng.net"); } ``` 在主函数中,可以通过 `pthread_join()` 接收线程返回的值: ```c int main() { int res; void *thread_result; pthread_t myThread; res = pthread_create(&myThread, NULL, ThreadFun, NULL); if (res != 0) { printf("线程创建失败"); return 0; } res = pthread_join(myThread, &thread_result); if (res != 0) { printf("等待线程失败"); } printf("%s\n", (char*)thread_result); return 0; } ``` ### 2. 通过 `pthread_cancel()` `pthread_cancel()` 函数用于请求取消一个线程的执行。被取消线程可以选择是否响应这个请求,具体行为取决于线程取消状态类型。例如: ```c #include <stdio.h> #include <pthread.h> #include <unistd.h> void *ThreadFun(void *arg) { while (1) { printf("线程正在运行\n"); sleep(1); } return NULL; } int main() { pthread_t myThread; pthread_create(&myThread, NULL, ThreadFun, NULL); sleep(3); // 让线程运行一段时间 pthread_cancel(myThread); // 请求取消线程 pthread_join(myThread, NULL); printf("线程终止\n"); return 0; } ``` ### 3. 通过 `return` 返回 线程可以通过直接从线程函数中返回来终止执行。这种方式是最简单且推荐的做法,尤其适用于线程任务完成时自然退出的情况。例如: ```c #include <stdio.h> #include <pthread.h> void *ThreadFun(void *arg) { printf("线程任务完成,准备退出\n"); return NULL; // 线程通过 return 返回 } int main() { pthread_t myThread; pthread_create(&myThread, NULL, ThreadFun, NULL); pthread_join(myThread, NULL); printf("线程终止\n"); return 0; } ``` ### 4. 使用布尔标志控制线程退出 有时需要主线程控制工作线程的退出,可以通过一个布尔标志来实现。工作线程定期检查该标志,如果标志被设置,则退出线程。例如: ```c #include <stdio.h> #include <pthread.h> #include <unistd.h> volatile int stop_thread = 0; void *ThreadFun(void *arg) { while (!stop_thread) { printf("线程正在运行\n"); sleep(1); } return NULL; } int main() { pthread_t myThread; pthread_create(&myThread, NULL, ThreadFun, NULL); sleep(3); // 让线程运行一段时间 stop_thread = 1; // 设置标志,通知线程退出 pthread_join(myThread, NULL); printf("线程终止\n"); return 0; } ``` ### 5. 使用事件对象(如条件变量) 对于更复杂的场景,可以使用条件变量或事件对象来通知线程退出。这种方式通常用于需要等待某些条件满足后再退出的场景。例如: ```c #include <stdio.h> #include <pthread.h> #include <unistd.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int stop_thread = 0; void *ThreadFun(void *arg) { while (1) { pthread_mutex_lock(&mutex); if (stop_thread) { pthread_mutex_unlock(&mutex); break; } pthread_mutex_unlock(&mutex); printf("线程正在运行\n"); sleep(1); } return NULL; } int main() { pthread_t myThread; pthread_create(&myThread, NULL, ThreadFun, NULL); sleep(3); // 让线程运行一段时间 pthread_mutex_lock(&mutex); stop_thread = 1; pthread_mutex_unlock(&mutex); pthread_join(myThread, NULL); printf("线程终止\n"); return 0; } ``` ### 总结 不同的线程终止方法适用于不同的场景。`pthread_exit()` `return` 适用于线程主动退出的情况,而 `pthread_cancel()` 布尔标志则适用于外部控制线程退出的场景。选择合适的方法可以提高程序的健壮性可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值