本节将给出 linux 下 c 语言多线程编程的例子 demo。
关键函数
在 linux 下实现多线程,关键函数是 pthread_create
函数。
- 函数简介
pthread_create是UNIX环境创建线程函数 - 头文件
#include<pthread.h> - 函数声明
int pthread_create(
pthread_t *restrict tidp,
const pthread_attr_t *restrict_attr ,
void*(*start_rtn)(void*),
void *restrict arg
);
- 返回值
若成功则返回0,否则返回出错编号 - 参数
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的地址。
最后一个参数是运行函数的参数。
下面给出一段 demo
#include "stdio.h"
#include "pthread.h"
#include "unistd.h"
void* myPrint()
{
int i = 5;
while(i--){
sleep(1);
printf("this is from myPrint\n");
}
}
int main()
{
pthread_t pid;
int res = pthread_create(&pid, NULL, myPrint, NULL);
sleep(6);
return 0;
}
因为pthread并非Linux系统的默认库,所以在编译时注意加上-lpthread
参数,以调用静态链接库。
$ gcc -pthread -o test.out test.c
$ ./test.out
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint
pthread_join 函数
上一部分给出的例子,在主函数中有一句 sleep(6);
,而 myPrint
函数只需 5 秒就可以执行完毕,所以打印出了 5 行 this is from myPrint
。如果将主函数中的sleep(6);
注释掉,会发生什么呢?
...
int main()
{
pthread_t pid;
int res = pthread_create(&pid, NULL, myPrint, NULL);
//sleep(6);
return 0;
}
编译执行,发现什么也没输出。myPrint
函数并没有阻塞程序退出,这不是我期望的。这时,可以使用 pthread_join
函数。
- 函数简介
函数pthread_join用来等待一个线程的结束。 - 函数原型为:
int pthread_join(pthread_t __th, void **__thread_return);
- 参数:
第一个参数为被等待的线程标识符
第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。 - 注意
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。如果执行成功,将返回0,如果失败则返回一个错误号。
这个函数是阻塞性的,它可以确保线程完整运行。而且还可以获取函数的返回值,下面是一个 demo。
#include "stdio.h"
#include "pthread.h"
#include "unistd.h"
void* myPrint()
{
int i = 5;
while(i--){
sleep(1);
printf("this is from myPrint\n");
}
}
int main()
{
pthread_t pid;
int res = pthread_create(&pid, NULL, myPrint, NULL);
//sleep(6);
pthread_join(pid, NULL);
return 0;
}
编译执行,
$ gcc -pthread -o test.out test.c
$ ./test.out
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint
this is from myPrint
发现myPrint
线程完毕后才退出,如何预期。
添加参数,获取返回值
pthread_create
函数的第四个参数就是输入参数的地方,只不过是 void*
型,需要类型转换一下。返回值则可以用 pthread_join 函数的第二个参数返回,也需要转换一下,下面是 demo:
没有什么难度,主要是建立了 DATA
结构体类型,用于转换数据。
#include "stdio.h"
#include "pthread.h"
#include "unistd.h"
typedef struct __DATA
{
int vint;
long vlong;
double vdouble;
}DATA;
void* myPrint(void* param)
{
DATA* data = (DATA*)param;
printf("this is from myPrint\n");
printf("param1: %d, param2: %ld, param3: %f\n",
data->vint, data->vlong, data->vdouble);
return (void*)"xrkzn.cn";
}
int main()
{
pthread_t pid;
int param1 = 11;
long param2 = 222;
double param3 = 333.44;
DATA data = {0};
data.vint = param1;
data.vlong = param2;
data.vdouble = param3;
pthread_create(&pid, NULL, myPrint, &data);
void* rtn;
pthread_join(pid, &rtn);
printf("myPrint return: %s\n", (char*)rtn);
return 0;
}
编译执行,一切符合预期。
$ gcc -pthread -o test.out test.c
$ ./test.out
this is from myPrint
param1: 11, param2: 222, param3: 333.440000
myPrint return: xrkzn.cn