#include<pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);
返回值
若成功则返回0,否则返回出错编号
参数
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的地址。
最后一个参数是运行函数的参数。
注意
在编译时注意加上-lpthread参数,以调用静态链接库。因为pthread并非Linux系统的默认库。
函数简介
函数pthread_join用来等待一个线程的结束。
函数原型为:
int pthread_join (pthread_t thread, void ** retval);
参数:
第一个参数为被等待的线程标识符
第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
注意
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。如果执行成功,将返回0,如果失败则返回一个错误号。
pthread_exit函数
函数介绍
函数使线程退出,并返回一个空指针类型的值。
一个线程的结束有两种途径:
①函数已经结束,调用它的线程也就结束了
②通过函数pthread_exit来实现
原型
void pthread_exit(void *retval)
参数
唯一的参数是函数的返回代码
pthread_join 和 pthread_exit的区别
pthread_exit(void *ptr) 函数使线程退出,并返回一个空指针类型的值。
pthread_join(pthread_t tid,void **rtval)调用此函数的进程/线程等id为tid的线程返回或被终止,并从它那里获得返回值。
#include <stdio.h>#include <pthread.h>//线程运行函数,返回值是void*类型,也就是返回通用指针,输入通用指针。在线程函数调用pthread_exit,以便返回值被主线程接受。void* say_hello(void* args){ /*线程的运行函数,必须void*,没说的表示返回通用指针、输入通用指针*/ printf("hello from thread\n"); pthread_exit((void*)1);}int main(){ pthread_t tid; //成功返回0; int iRet = pthread_create(&tid, NULL, say_hello, NULL); /*参数依次是:创建的线程id,线程参数,调用函数名,传入的函数参数*/ if (iRet){ printf("pthread_create error: iRet=%d\n",iRet); return iRet; } //调用pthread_jion函数,获得线程的饭hi之。 void *retval; iRet=pthread_join(tid,&retval); if (iRet){ printf("pthread_join error: iRet=%d\n",iRet); return iRet; } printf("retval=%ld\n",(long)retval); return 0;}
编译 g++ -lpthread -o test test.cpp,这里需要连接静态库文件pthread。执行./test命令可以得到
用Hello::say_hello传入调用函数
#include <stdio.h>#include <pthread.h>class Hello{public: static void* say_hello(void* args){ /*线程的运行函数,必须void*,没说的表示返回通用指针、输入通用指针*/ printf("hello from thread\n"); pthread_exit((void*)1); }};int main(){ pthread_t tid; int iRet = pthread_create(&tid, NULL, Hello::say_hello, NULL); /*参数依次是:创建的线程id,线程参数,调用函数名,传入的函数参数*/ if (iRet){ printf("pthread_create error: iRet=%d\n",iRet); return iRet; } void *retval; iRet=pthread_join(tid,&retval); if (iRet){ printf("pthread_join error: iRet=%d\n",iRet); return iRet; } printf("retval=%ld\n",(long)retval); return 0;}
#include <stdio.h>#include <pthread.h>void* say_hello(void* args){ int i=*(int*)args; printf("hello from thread,i=%d\n",i); pthread_exit((void*)1);}int main(){ pthread_t tid; int para=10; //给线程调用的函数传递一个int类型的参数para,值是10 int iRet = pthread_create(&tid, NULL, say_hello, ¶); if (iRet){ printf("pthread_create error: iRet=%d\n",iRet); return iRet; } void *retval; iRet=pthread_join(tid,&retval); if (iRet){ printf("pthread_join error: iRet=%d\n",iRet); return iRet; } printf("retval=%ld\n",(long)retval); return 0;}
传入时直接引用结构体地址即可
#include <stdio.h>#include <pthread.h>#include <string.h>struct arg_type{ int a; char b[100];};void* say_hello(void* args){//进行类型转换 arg_type arg_temp=*(arg_type*)args; printf("hello from thread,arg_temp.a=%d, arg_temp.b=%s\n",arg_temp.a,arg_temp.b); pthread_exit((void*)1);}int main(){ pthread_t tid; arg_type arg_temp; arg_temp.a=10; char temp[100]="I am number one."; strncpy(arg_temp.b,temp,sizeof(temp)); int iRet = pthread_create(&tid, NULL, say_hello, &arg_temp); if (iRet){ printf("pthread_create error: iRet=%d\n",iRet); return iRet; } void *retval; iRet=pthread_join(tid,&retval); if (iRet){ printf("pthread_join error: iRet=%d\n",iRet); return iRet; } printf("retval=%ld\n",(long)retval); return 0;}
有两种方式可以打印线程的ID
①在线程调用函数中使用pthread_self函数来获得线程ID
②在创建函数生成的ID。
//第一种void *function(void *arg){ printf("thread id in pthread = %lu\n",pthread_self());}
//第二种int main(){ int i = 10; pthread_t thread; int iRet = pthread_create(&thread,NULL,&function,&i); if(Ret){} printf("pthread id in process = %lu\n",thread);}