1、核心理论
为什么需要线程?
为了提高完成一个任务的速度,我们创建了多个进程去完成一个任务,但是多个进程间有相同的地方(例如代码相同,所使用的数据相同),同时工作时就造成了资源的浪费;为了避免资源浪费,我们进程间相同的部分分割出来,不同的部分就形成了一个小小的线程。线程概念(特点):
· 线程就是“轻量级”的进程。(linux中不存在线程这个机制)
· 线程与创建他的进程共享代码段、数据段。
· 线程拥有自己的独立的栈。注意:
1.轻量级是指多个线程线程共享同一个数据段,代码段,这个代码段也是创建它的进程的代码段和数据段,这也是线程与进程的区别。
2.多线程理解:多个线程按一定的顺序执行去完成某项任务,这些线程使用共同的数据段,代码段。
3.当一个进程结束时,那么他所创建的线程也会结束;如果不想让其结束那就要用到线程等待函数。
4.再调用线程相关函数时,编译程序时必须链接函数库::-lpthread
5.为什么线程退出函数不使用exit函数?
因为exit是用来退出进程的,用在线程中会导致创建该线程的进程退出,进程退出了,那么所创建的所有线程都会退出。
2.函数学习
- 创建线程
函数名:pthread_create
函数原型:int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine) (void*),void *arg)
函数功能:创建一个进程
所属头文件:pthread.h
特别注意:编译时必须链接pthread库(gcc -lpthread)
返回值:成功返回0,失败返回一个错误号
参数说明:thread
:新创建的线程的id,attr
:创建线程的属性,start_routine
:指明线程要执行的函数的(线程的入口函数),arg
:线程入口函数的参数,
等待线程结束
函数名:pthread_join
函数原型:pthread_join(pthread_t thread,void **retval)
函数功能:等待线程结束
所属头文件:pthread.h
返回值:成功返回0,失败返回错误编号
参数说明:thread
:要等待结束的线程id,retval
:保存线程退出的状态退出线程
函数名:pthread_exit
函数原型:void pthread_exit(void *retval)
函数功能:退出线程
所属头文件:pthread.h
返回值:空
参数说明:retval
:保存返回值
3.线程互斥
概念:
在实际应用中,多个线程往往会访问同一数据或者资源,为了避免线程之间相互影响,需要引入线程互斥机制,而互斥锁(mutex)是互斥机制中的一种。(多进程并发时中引入的是信号量。)初始化互斥锁函数
pthread_mutex_init获取互斥锁函数
pthread_mutex_lock释放互斥锁函数
pthread_mutex_unlock
4.综合实例
- 两人垒墙问题
(1)线程1
创建线程
等待线程结束
结束线程
(2)线程2
创建线程
等待线程结束
结束线程
#include <pthread.h>
#include <stdio.h>
pthread_t thread[2];
int number = 0;
pthread_mutex_t mut;
void * worker1()
{
int i = 0;
printf("I am worker1!\n");
for (i = 0;i < 10;i++)
{
pthread_mutex_lock(&mut);
number++;
pthread_mutex_unlock(&mut);
printf("worker1 number %d\n",number);
sleep(1);
}
pthread_exit(NULL);
}
void * worker2()
{
int i = 0;
printf("I am worker2!\n");
for (i = 0;i < 10;i++)
{
pthread_mutex_lock(&mut);
number++;
pthread_mutex_unlock(&mut);
printf("worker2 number %d\n",number);
sleep(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_mutex_init(&mut,NULL);
//1.creat worker1 thread
pthread_create(&thread[0],NULL,worker1,NULL);
//2.creat worker2 thread
pthread_create(&thread[1],NULL,worker2,NULL);
//3.wait worker1 thread over
pthread_join(thread[0],NULL);
//4.wait worker2 thread over
pthread_join(thread[1],NULL);
return 0;
}