进程线程模型
- 线程是调度的基本单位,进程是资源分配的基本单位
多线程模型
1. 线程创建和结束
-
背景知识:
在一个文件内的多个函数通常都是按照main函数中出现的顺序来执行,但是在分时系统下,我们可以让每个函数都作为一个逻辑流并发执行,最简单的方式就是采用多线程策略。
在main函数中调用多线程接口创建线程,每个线程对应特定的函数(操作),这样就可以不按照main函数中各个函数出现的顺序来执行,避免了忙等的情况。线程基本操作的接口如下。 -
相关接口:
-
创建线程:int pthread_create(pthread_t *pthread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *agr);
创建一个新线程,pthread和start_routine不可或缺,分别用于标识线程和执行体入口,其他可以填NULL。
- pthread:用来返回线程的tid,*pthread值即为tid,类型pthread_t == unsigned long int。
- attr:指向线程属性结构体的指针,用于改变所创线程的属性,填NULL使用默认值。
- start_routine:线程执行函数的首地址,传入函数指针。
- arg:通过地址传递来传递函数参数,这里是无符号类型指针,可以传任意类型变量的地址,在被传入函数中先强制类型转换成所需类型即可。
-
获得线程ID:pthread_t pthread_self();
调用时,会打印线程ID。
-
等待线程结束:int pthread_join(pthread_t tid, void** retval);
主线程调用,等待子线程退出并回收其资源,类似于进程中wait/waitpid回收僵尸进程,调用pthread_join的线程会被阻塞。
- tid:创建线程时通过指针得到tid值。
- retval:指向返回值的指针。
-
结束线程:pthread_exit(void *retval);
子线程执行,用来结束当前线程并通过retval传递返回值,该返回值可通过pthread_join获得。
- retval:同上。
-
分离线程:int pthread_detach(pthread_t tid);
主线程、子线程均可调用。主线程中pthread_detach(tid),子线程中pthread_detach(pthread_self()),调用后和主线程分离,子线程结束时自己立即回收资源。
- tid:同上。
-
2. 线程同步
-
Linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。
-
互斥锁(mutex)
锁机制是同一时刻只允许一个线程执行一个关键部分的代码。-
初始化锁:int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);
其中参数mutex为指向需要初始化的互斥锁的指针,参数mutexattr用于指定锁的属性,如果为NULL则使用缺省属性。
-
阻塞加锁:int pthread_mutex_lock(pthread_mutex *mutex);
其中参数mutex为指向需要获取的互斥锁的指针
-
非阻塞加锁:int pthread_mutex_trylock( pthread_mutex_t *mutex);
该函数语义与 pthread_mutex_lock() 类似,不同的是在锁已经被占据时返回 EBUSY 而不是挂起等待。
-
解锁(要求锁是lock状态,并且由加锁线程解锁):int pthread_mutex_unlock(pthread_mutex *mutex);
其中参数mutex为指向需要释放的互斥锁的指针
-
销毁锁(此时锁必需是unlock状态,否则返回EBUSY):int pthread_mutex_destroy(pthread_mutex *mutex);
其中参数mutex为指向需要释放的互斥锁的指针
-
-
条件变量(cond)
条件变量是利用线程间共享全局变量进行同步的一种机制。条件变量上的基本操作有:触发条件(当条件变为 true 时);等待条件&