//--------对于线程函数多个参数--------------
#include<stdio.h>
#include<pthread.h>
typedef struct //形参结构体
{
int a; //学号
char name[10]; //姓名
int b; //年龄
}pr;
//线程运行的函数
void *fun(pr *n) //void *fun(void *n)
{
/* void * 类型的函数为固定结构,因为pthread_create()
* 函数的第三个参数类型为 void * ,上下应保持一致;
* 形参只有一个(与pthread_create() 的第四个参数类
* 保持一致【一般使用 void *类型】),如果需要传入
* 多个形参,则将参数封装到结构体中,然后将结构体
* 变量的地址传入该形参。
*/
printf("学号为:%d\n",n->a);
printf("姓名为:%s\n",n->name);
printf("年龄为:%d\n",n->b);
}
int main()
{
int len,lens;
pthread_t tmp; //定义一个线程的标识符
pr p1; //定义一个结构体变量(封装线程函数所需的参数)
p1=(pr){1,"tian",23}; //结构体变量初始化
//创建线程
len = pthread_create(&tmp,NULL,(void *)fun,&p1);
/*
* int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void *)(*start_rtn)(void *) ,void *arg);
* 第一个参数为指向线程标识符的指针;
* 第二个参数用来设置线程属性;
* 第三个参数是线程运行函数的起始地址(即线程运行的函数名);
* 第四个参数是运行函数的参数(很多时候参数不止一个,此时将参数封装在一个结构体中,然后将结构体变量的地址传入);
*
* 返回值: 成功返回 0 ,失败返回错误编号。
*
*/
printf("pthread_create的返回值(len) == %d\n",len);
lens = pthread_join(tmp,NULL);//等待线程运行结束
/*pthread_join()函数以阻塞的方式等待 thread 指定的线程结束
* int pthread_join(pthread_t thread,void **retval);
* 第一个参数表示被连接的线程号;
* 第二个参数指向一个指向被连接线程的返回码的指针的指针,retval 是用户定义
* 的指针,用来存储等待线程的返回值。【这个一般用不上,用NULL来代替】
*
* 返回值:成功返回0 ,失败返回一个错误号。
* */
printf("pthread_join 的返回值(lens) == %d\n",lens);
printf("123\n");
return 0;
}
pthread_join() 的两种作用
1)用于等待其他线程结束;
2)对线程的资源进行回收。
- 当调用 pthread_join() 时,当前线程会处于阻塞状态,直到被调用的线程结束后,当前线程才会重新开始执行。
- 当 pthread_join() 函数返回后,被调用线程才算真正意义上的结束,它的内存空间也会被释放(如果被调用的线程是非分离的)。
- 线程被释放的内存空间仅仅是系统空间,程序分配的空间必须手动清除,如: malloc() 分配的空间。
//------------对于线程函数单个参数----------
#include<stdio.h>
#include<pthread.h>
void fun(void *n)
{
int x = *(int *)n;
printf("线程输出: %d\n",x);
}
int main()
{
int num = 4;
pthread_t p;
pthread_create(&p,NULL,(void *)fun,(void *)&num);
printf("主线程执行\n");
pthread_join(p,NULL);
return 0;
}
【在编译时注意在最后加上 -lpthread ,以调用静态链接库。因为pthread 并非 Linux系统的默认库。】