weiqi7777

进击吧,linux(十九) 多线程编程

0
阅读(3564)

线程,被称为轻量级进程,相比多进程,有以下两点不同:

1、线程和创建他的进程共享代码段、数据段

2、线程拥有自己独立的栈


同样,对于多线程编程学习,也是基于几个函数的学习。

11.1创建线程

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所属头文件

创建线程需要链接pthreadgcc –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等待线程结束

11.2.1函数名

pthread_join

11.2.2函数原形

Int pthread_join(pthread_t thread, void **retval)

11.2.3函数功能

等待thread的线程结束

11.2.4所属头文件

需要链接pthreadgcc –lpthread

11.2.5返回值

成功:0

失败:错误编码

-EDEADLK: deadlock was detected

-EINVAL:线程不可等待

-ESRCH:线程ID不正确

11.2.6参数说明

thread要等待结束的线程ID

retval保存线程时退出的状态,一般为NULL,不保存

11.2.7示例代码

11.3退出线程

11.3.1函数名

pthread_exit

11.3.2函数原形

void pthread_exit(void *retval)

11.3.3函数功能

结束线程

11.3.4所属头文件

需要链接pthreadgcc –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对程序进行编译,然后再执行。发现,执行两次的结果不一样,可以看出,对于多线程,执行的顺序不是固定的。不是谁先创建就先执行哪一个线程。

clip_image002


以上,就是多线程编程的学习了,但是也只是学习了多线程的基本使用,但是问题来了,因为多线程是共享主进程的数据段,那如果多个线程同时对一个数据进行操作的话,又怎么处理了,按照之前学习的,肯定就想到了信号量的互斥,但是在多线程中,是不用这个信号量的,是使用互斥锁。

Baidu
map