Linux多线程基础学习(四)线程的终止、连接、取消

来源:互联网 发布:json 中文乱码 编辑:程序博客网 时间:2024/06/04 18:05

线程终止:

1、 如果进程中的任意一个线程调用了exit,_Exit,_exit,那么整个进程就会终止

2、 从启动例程中返回,返回值是线程的退出码

3、 线程可以被同一进程中的其他线程取消

4、 线程调用pthread_exit(void *rval)函数,rval是退出码


#include <stdio.h>#include <iostream>#include <pthread.h>#include <stdlib.h>#include <string.h>using namespace std;int method = 1;void *thread_fun(void *arg){//如果传到参数1,那么就采用return方式退出if(method==1){cout<<"new thread using return!"<<endl;return (void *)1;}//如果传入参数2,那么就采用pthreade_xit方式退出if(method==2){cout<<"new thread using pthread_exit!"<<endl;pthread_exit((void *)2);}//如果传入参数3,那么就采用exit方式退出if(method==3){cout<<"new thread using exit!"<<endl;exit(3);}return 0;}int main(int argc, char *argv[]){int err;pthread_t tid;err = pthread_create(&tid, NULL, thread_fun, (void *)argv[1]);if(err != 0){cout<<"create new  thread failed"<<endl;return 0;}void *status;pthread_join(tid, &status);cout<<"main thread"<<endl;cout<<"new thread's exit status: "<<(int)status<<endl;return 0;}



线程连接:

int pthread_join(pthead_ttid, void **rval)

调用该函数的线程会一直阻塞,直到指定的线程tid调用pthread_exit、从启动例程返回或者被取消

参数tid就是指定线程的id

参数rval是指定线程的返回码,如果线程被取消,那么rval被置为PTHREAD_CANCELED

该函数调用成功会返回0,失败返回错误码

 

调用pthread_join会使指定的线程处于分离状态,如果指定线程已经处于分离状态,那么调用就会失败

pthread_detach可以分离一个线程,线程可以自己分离自己

intpthread_detach(pthread_t thread);

成功返回0,失败返回错误码


#include <stdio.h>#include <iostream>#include <pthread.h>using namespace std;void *thread_fun1(void *arg){cout<<"thread 1 is runing"<<endl;return (void *)1;}void *thread_fun2(void *arg){cout<<"thread 2 is runing"<<endl;pthread_detach(pthread_self());pthread_exit((void *)2);}int main(){int err1, err2;pthread_t tid1, tid2;void *rval1, *rval2;err1 = pthread_create(&tid1, NULL, thread_fun1, NULL);err2 = pthread_create(&tid2, NULL, thread_fun2, NULL);if(err1 || err2){cout<<"create new thread failed"<<endl;return 0;}cout<<"main is runing"<<endl;cout<<"1 join err code is: "<<pthread_join(tid1, &rval1)<<endl;cout<<"2 join err code is: "<<pthread_join(tid2, &rval2)<<endl;cout<<"thread 1 return code is: "<<std::oct<<(int)(int *)rval1<<endl;cout<<"thread 2 return code is: "<<std::oct<<(int)(int *)rval2<<endl;cout<<"main is ended"<<endl;return 0;}



线程1连接正常,线程二由于分离后释放资源导致无法连接返回错误码22,return值也没有成功获取。


线程取消

取消函数原型

int pthread_cancle(pthread_ttid)

取消tid指定的线程,成功返回0。取消只是发送一个请求,并不意味着等待线程终止,而且发送成功也不意味着tid一定会终止

用于取消一个线程,它通常需要被取消线程的配合。线程在很多时候会查看自己是否有取消请求。

如果有就主动退出,这些查看是否有取消的地方称为取消点。

取消状态,就是线程对取消信号的处理方式,忽略或者响应。线程创建时默认响应取消信号

 设置取消状态函数原型

int pthread_setcancelstate(int state, int*oldstate) 

设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,

 

分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。

取消类型,是线程对取消信号的响应方式,立即取消或者延时取消。线程创建时默认延时取消

设置取消类型函数原型

int pthread_setcanceltype(int type, int*oldtype)

设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如果不为NULL则存入运来的取消动作类型值。

 

取消一个线程,它通常需要被取消线程的配合。线程在很多时候会查看自己是否有取消请求

如果有就主动退出,这些查看是否有取消的地方称为取消点

 

很多地方都是包含取消点,包括

pthread_join()、pthread_testcancel()、pthread_cond_wait()、 pthread_cond_timedwait()、sem_wait()、sigwait()、write、read,大多数会阻塞的系统调用


#include <stdio.h>#include <iostream>#include <pthread.h>#include <stdlib.h>#include <string.h>using namespace std;void *thread_fun(void *arg){int stateval;int typeval=0;//设置线程disable取消,此操作有点类似关中断,哈哈stateval = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);if(stateval != 0){printf("set cancel state failed\n");}printf("Im new thread,wait 4s\n");//sleep(4);//在等待的4s时间里主线程调用取消函数printf("about to cancel \n");//设置线程enable取消stateval = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);if(stateval != 0){printf("set cancel state failed\n");}typeval = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);//typeval = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);if(typeval != 0){printf("set cancel type failed\n");}printf("first cancel point\n");printf("second cancel point\n");return (void *)20;}int main(){pthread_t tid ;int err, cval, jval;void *rval;err = pthread_create(&tid, NULL, thread_fun, NULL);if(err != 0){printf("create thread failed\n");return 0;}sleep(2);printf("canceling new thread!\n");cval = pthread_cancel(tid);//等待两秒取消子线程if(cval != 0){printf("cancel thread failed\n");}jval = pthread_join(tid, &rval);printf("new thread exit code is %d\n", (int *)rval);return 0;}



0 0