进击吧,linux(十九) 多线程编程
0赞线程,被称为轻量级进程,相比多进程,有以下两点不同:
1、线程和创建他的进程共享代码段、数据段
2、线程拥有自己独立的栈
同样,对于多线程编程学习,也是基于几个函数的学习。
11.1.1函数名
pthread_create
11.1.2函数原形
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *),void *arg)
11.1.3函数功能
创建新的线程
11.1.4所属头文件
创建线程需要链接pthread库gcc –lpthread
11.1.5返回值
成功:0
失败:错误编码
-EAGAIN:没有资源创建新线程
-EINVAL:无效的属性设置
-EPERM:没有权限设置属性中的一些参数
11.1.6参数说明
thread:线程ID,创建成功的话,*thread会保存创建的线程的ID。
attr:指定创建线程的属性,如果为NULL,使用默认属性
start_routine:创建的线程执行的入口函数
arg:线程入口函数的参数,可以为NULL
11.1.7示例代码
11.2.1函数名
pthread_join
11.2.2函数原形
Int pthread_join(pthread_t thread, void **retval)
11.2.3函数功能
等待thread的线程结束
11.2.4所属头文件
需要链接pthread库gcc –lpthread
11.2.5返回值
成功:0
失败:错误编码
-EDEADLK: deadlock was detected
-EINVAL:线程不可等待
-ESRCH:线程ID不正确
11.2.6参数说明
thread:要等待结束的线程ID
retval:保存线程时退出的状态,一般为NULL,不保存
11.2.7示例代码
11.3.1函数名
pthread_exit
11.3.2函数原形
void pthread_exit(void *retval)
11.3.3函数功能
结束线程
11.3.4所属头文件
需要链接pthread库gcc –lpthread
11.3.5返回值
函数没有返回
11.3.6参数说明
retval:保存退出的返回值
11.3.7示例代码
下面,就编写代码来对上面几个函数进行学习。
代码实现的功能,就是创建3个线程,分别传入三个参数,然后各个线程打印自己的内容。
#include "pthread.h" #include "stdio.h" void *fun_1(void *str) { //将输入的参数强制转化成char *类型 printf("%s\n",(char *)str); sleep(2); pthread_exit(NULL); } void *fun_2(void *a) { //将输入的参数强制转化成int *类型 printf("%d\n",*(int *)a); sleep(3); pthread_exit(NULL); } void *fun_3(void *nul) { printf("welcome to weiqi7777 blog\n"); sleep(4); pthread_exit(NULL); } int main() { pthread_t thread[3]; int arg=5; //创建线程1 pthread_create(&thread[0],NULL,fun_1,(void *)"hello weiqi7777"); //创建线程2 pthread_create(&thread[1],NULL,fun_2,(void *)&arg); //创建线程3 pthread_create(&thread[2],NULL,fun_3,NULL); //等待线程1结束 pthread_join(thread[0],NULL); //等待线程2结束 pthread_join(thread[1],NULL); //等待线程3结束 pthread_join(thread[2],NULL); exit(0); }
这里,要注意的有几个地方。
1、创建线程的时候,第一个参数是传入线程标识符的地址,所以在这里是&thread[0]
2、创建线程的最后一个是传入的参数,按照规定的,这个参数的类型是void *,所以在这里对传入的参数进行强制类型转化,防止编译有警告
3、对于线程的函数,类型是void *(*)(void *)类型的,所以线程的函数要按照这个类型进行定义,不然会报错或者警告
4、线程执行完毕后,要调用pthread_exit进行线程的退出
5、主进程中,一定要等待所有线程执行完毕后,才能退出程序,否则当退出程序后,没有执行完毕的线程就直接被退出了。
执行程序,首先是用gcc –lpthread对程序进行编译,然后再执行。发现,执行两次的结果不一样,可以看出,对于多线程,执行的顺序不是固定的。不是谁先创建就先执行哪一个线程。
以上,就是多线程编程的学习了,但是也只是学习了多线程的基本使用,但是问题来了,因为多线程是共享主进程的数据段,那如果多个线程同时对一个数据进行操作的话,又怎么处理了,按照之前学习的,肯定就想到了信号量的互斥,但是在多线程中,是不用这个信号量的,是使用互斥锁。