- 进程概述
- 线程创建
- 线程退出
- pthread_exit函数
- pthread_cancel函数
- pthread_join函数(回收线程)
- 线程分离pthread_detach
- 线程属性
进程:有独立的进程地址空间,有独立的PCB
线程:没有独立的地址空间,是共享的,有独立的PCB
Linux下,线程是最小的执行单位,进程是最小的分配资源的单位
LWP: 轻量级进程也就是线程
命令
ps -Lf pid
可以查看该进程的线程号
int pthread_create(pthread_t *thread, //传出参数,表示创建的线程的线程id
const pthread_attr_t *attr, //表示线程属性,传NULL表示使用默认属性
void *(*start_routine) (void *),//回调函数,会自动调用
void *arg); //上一个参数的参数
返回值:成功返回0
失败返回perror
#include线程退出 pthread_exit函数#include #include #include void* tfn(void*arg) { printf("phread:pid = %d,tid = %lun",getpid(),pthread_self()); } int main() { pthread_t tid; printf("mian : pid = %d ,tid = %lun",getpid(),pthread_self()); int ret=pthread_create(&tid,NULL,tfn,NULL); if(ret!=0) { perror("pthread"); } sleep(1); return 0; }
void pthread_exit(void *retval);
参数是传出参数,此函数的作用是终止一个调用他的线程
eg:循环创建五个子线程,终止第三个子线程
#include#include #include #include #include void func() { pthread_exit(NULL); } void*tfn(void*argv) { int i=(int)argv; sleep(i); if(i==2)//第三个线程退出 { // exit(1);//表示退出进程 //return NULL;//表示返回到函数调用者那里 func(); } printf("I am %d ,pthread: pid = % d,tid = %lun",i+1,getpid(),pthread_self()); } int main() { int i=0; int ret; pthread_t tid; for(i=0;i<5;i++) { ret=pthread_create(&tid,NULL,tfn,(void*)i); if(ret!=0) { perror("pthread_create"); exit(1); } } //sleep(i); printf("i am mainn"); //return 0; pthread_exit(NULL); }
执行结果:
int pthread_cancel(pthread_t thread);
回收特定线程,传入参数是要终止的线程id
为了看到效果,用一个死循环代码来展示效果
#include#include #include #include #include #include void*tnf(void*arg) { while(1) { printf(" thread: pid = %d,tid = %lun",getpid(),pthread_self()); sleep(1); } } int main() { pthread_t tid; int ret =pthread_create(&tid,NULL,tnf,NULL); if(ret<0) { perror("create"); exit(1); } sleep(3); ret=pthread_cancel(tid); while(1); return 0; }
效果:
阻塞等待线程退出,并且获得线程退出状态(返回值),很类似于进程中的waitpid函数
int pthread_join(pthread_t thread, void **retval);
参数:
thread 要堵塞等待退出的线程id
retval 退出状态
eg:
#include#include #include #include #include #include typedef struct pdf { int var; char arr[100]; }pdf; void*tnf(void*arg) { struct pdf* p1; p1=(pdf*)malloc(sizeof(pdf)); p1->var=100; strcpy(p1->arr,"hello world"); return (void*)p1; } int main() { pthread_t tid; pdf* p1; int ret =pthread_create(&tid,NULL,tnf,NULL); pthread_join(tid,(void**)&p1); printf("tar=%d,arr=%sn",p1->var,p1->arr); return 0; }
结果:
线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其它线程获取,而直接自己自动释放
int pthread_detach(pthread_t thread);
参数:所要分离的线程
#include#include #include #include #include #include void*tfn(void*arg) { printf("thread : pid = %d, tid = %lun",getpid(),pthread_self()); return NULL; } int main() { pthread_t tid; int ret=pthread_create(&tid,NULL,tfn,NULL); if(ret!=0) { perror("create error"); exit(1); } sleep(2); ret=pthread_detach(tid); if(ret!=0) { fprintf(stderr,"pthread_deach error:%sn",strerror(ret)); exit(1); } ret=pthread_join(tid,NULL); if(ret!=0) { fprintf(stderr,"pthread_join error:%sn",strerror(ret)); exit(1); } return 0; }
结果:
当我们对线程分离后,再当我们使用线程退出函数就会报无效参数的错误
属性值不能直接设置,须使用相关函数进行操作,初始化的函数为pthread_attr_init,这个函数必须在pthread_create函数之前调用。之后须用pthread_attr_destroy函数来释放资源。线程属性主要包括如下属性:作用域(scope)、栈尺寸(stack size)、栈地址(stack address)、优先级(priority)、分离的状态(detached state)、调度策略和参数(scheduling policy and parameters)。默认的属性为非绑定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。
所用函数
int pthread_attr_init(pthread_attr_t *attr);//初始化 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);//设置分离非分离属性 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachst ..........还有很多函数 int pthread_attr_destroy(pthread_attr_t *attr);//销毁
使用
#include#include #include #include #include #include void*tfn(void*argv) { printf("thread : pid=%d,tid=%lun",getpid(),pthread_self()); return NULL; } int main() { pthread_attr_t attr; pthread_t tid; int ret=pthread_attr_init(&attr); //初始化 if(ret!=0) { fprintf(stderr,"attr_init error:%sn",strerror(ret)); exit(1); } ret=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//设置线程属性为分离属性 if(ret!=0) { fprintf(stderr,"attr_setdeatachstate error:%sn",strerror(ret)); exit(1); } ret=pthread_create(&tid,&attr,tfn,NULL); if(ret!=0) { fprintf(stderr,"attr_create error:%sn",strerror(ret)); exit(1); } ret=pthread_attr_destroy(&attr);//销毁 if(ret!=0) { fprintf(stderr,"attr_destroy error:%sn",strerror(ret)); exit(1); } sleep(1); ret=pthread_join(tid,NULL);//测试是否成功分离线程 if(ret!=0) { fprintf(stderr,"create error:%sn",strerror(ret)); exit(1); } return 0; }



