pthread_xxx 错误检查
- 传统的一些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指示错误。
- pthreads函数出错时
不会设置全局变量errno
(而大部分其他POSIX函数会这样做)。而是将错误代码通过返回值返回
- pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码。
- 对于pthreads函数的错误,建议通过返回值判定,因为读取返回值要比读取线程内的errno变量的开销更小对于pthreads函数的错误
pthread_t pthread_self
(void); 返回线程ID
int pthread_create(
pthread_t *thread, //传出参数:线程ID=unsigned long
const pthread_attr_t *attr, //设置线程的属性,attr为NULL表示使用默认属性
void *(*start_routine) (void *), //线程回调函数
void *arg //线程回调函数的参数
);
成功,返回0;失败,返回错误号
注解1:perror()不能使用该函数打印错误信息,而是使用strerror(ret),打印错误码
注解2:主线程先退出,子线程会被强制结束
int pthread_equal
(pthread_t t1, pthread_t t2);
实际上该函数很少用,线程ID是unsigned long数据类型,可以直接对比两个值是否相等来判断两个线程的ID是否相等,进而判断是否为同一个线程。
int pthread_join
(pthread_t thread, void **retval); ① 使主线程等待线程ID=thread子线程执行完后,主线程才退出;② 通过pthread_exit / return获取子线程的传来的数据
pthread_detach
:使线程在创建后脱离主线程,脱离的线程在终止时,所有的相关资源将会被自动释放。
void pthread_exit
(void *retval); // 参数retval不要指向一个局部变量
知识点1—向线程函数传递参数
情况1:int类型的实参(直接强转就OK)
void* myfunc(void* arg){ //形参 arg
//直接将arg强制转换成int就可以使用
printf("%dth child thread id = %lu\n",(int)arg,pthread_self()); // (int)arg
}
int main(){
pthread_t tid;
int i;
pthread_create(&tid,NULL,myfunc,(void*)i); // 实参 (void*)i
}
情况2:非int类型的实参
① 在main线程中,malloc一个空间保存实参
② 在子线程中,强转后使用,使用完成之后free释放资源
知识点2—线程函数向主线程函数传回数据
在线程函数中,使用pthread_exit函数,可以将thread_func中的非局部变量
传递给主线程;主线程中使用pthread_join函数接收该非局部变量的值;pthread_join函数的第二个参数void *retval将会接收到pthread_exit(void retval)传回来的值。
Q:pthread_exit和pthread_join函数是怎么进行数据传递的?
答:调用pthread_join(tid,&ptr)函数后,ptr指针与pthread_exit的参数指向同一块内存
代码案例—返回线程函数中的值
struct node{
int data;
char buf[1024];
};
void* thread_func(void* arg){
struct node* nd=(struct node*)malloc(sizeof(struct node)); //非局部变量
nd->data=100;
strcpy(nd->buf,"Thunder");
//将线程函数中的非局部变量值,通过pthread_exit/return的方式“甩给”主线程
//pthread_exit(nd); //方法1
return nd; //方法2
}
int main(){
pthread_t tid;
int ret=pthread_create(&tid,NULL,thread_func,NULL);
if(ret!=0)
printf("ret=%d,error=%s\n",ret,strerror(ret));
void* retval=NULL;
pthread_join(tid,&retval); //主线程接收线程函数中“甩出来”的值
printf("%d,%s\n",((struct node*)retval)->data,((struct node*)retval)->buf);
}