一、概念
进程:进程是一个具有一定独立功能的程序的一次运行活动,同时也是资源分配的最小单元;
进程是程序执行时的一个实例,即它是程序已经执行到某种程度的数据结构的汇集。从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。
Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点,每个进程都是一个独立的运行单位,拥有各自的权利和责任。其中,各个进程都运行在独立的虚拟地址空间,因此,即使一个进程发生异常,它也不会影响到系统中的其他进程。
线程:是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。通俗的说,一个进程可以有很多线程,但对于一个线程来说,它只能属于一个进程。
二、进程与线程的区别
基本单位 | 稳定性 | 资源 | 地址空间 | |
---|---|---|---|---|
进程 | 资源分配的最小单元 | 强健,一个进程崩溃,其他进程依旧可以进行 | 耗费资源较大,效率低,速度慢 | 拥有单独的地址空间 |
线程 | CPU调度和分派的基本单位 | 脆弱,一个线程崩溃,整个进程结束 | 耗费资源少,效率高,速度快 | 没有独立的地址空间,同一进程的所有线程共享进程的地址空间 |
三、线程与进程的优缺点
a.线程的优点:
1.运行于一个进程中的多个线程,它们之间使用相同的地址空间,和进程相比,它是一种非常“节俭”的多任务作方式
2.线程间彼此切换所需的时间远远小于进程间切换所需要的时间
3.线程间方便的通信机制,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。
4.使多CPU系统更加有效
5.改善程序结构
线程的缺点:
线程比较脆弱,当一个线程崩溃,相当于整个进程崩溃;
b.进程的优点:
进程拥有独立的地址空间,一个进程崩溃不会对其他进程产生影响,所以多进程的程序要比多线程的程序健壮
进程的缺点:
在进程切换时,耗费资源较大,效率要差,对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
四、 线程的创建、回收、取消、分离、同步
1、线程的创建:
int pthread_create(pthread_t * tidp,const pthread_attr_t*attr,void*(*start_rtn)(void),void*arg)
pthread_t * tidp :线程号
const pthread_attr_t*attr :属性、一般为NULL
void*(*start_rtn)(void) : 线程号
void*arg : arg为线程函数的形参,如果没有写NULL
2、线程的回收:int pthread_join(pthread_t thread, void **value_ptr);
阻塞调用线程,直到指定的线程终止
pthread_t thread:线程号
void **value_ptr:线程退出状态
3、线程的取消 :一个线程取消另一个线程 int pthread_cancel(pthread_t thread);
pthread_t thread:进程号
取消属性(写在被取消的线程函数内):
int pthread_setcanceltype(int type, int *oldtype);
type: PTHREAD_CANCEL_DISABLE (不响应取消信号) PTHREAD_CANCEL_ASYNCHRONOUS (立即取消)
4、线程的分离 :
线程执行后,自行释放(取代join)
int pthread_detach(pthread_t thread);
一般情况下,我们将形参写成:pthread_self(),即可将自身释放
5、线程的同步 :
互斥量(Mutex)、信号灯、条件变量
1、互斥量
定义互斥量(全局)、主线程中初始化(函数、宏)、访问共享资源前加锁、结束时解锁
定义互斥量: pthread_mutex_t mutex;
初始化:
- 1
- 2
pthread_mutex_t *restrict mutex : &mutex
const pthread_mutexattr_t *restrict attr : NULL
或者使用宏定义来初始化:
- 1
- 2
加锁:
对共享资源的访问, 要使用互斥量进行加锁, 如果互斥量已经上了锁, 调用线程会阻塞, 直到互斥量被解锁。
- 1
- 2
trylock是非阻塞调用模式, 如果互斥量没被锁住, trylock函数将对互斥量加锁, 并获得对共享资源的访问权限; 如 果互斥量被锁住了,trylock函数将不会阻塞等待而直接返回EBUSY, 表示共享资源处于忙状态
解锁:
在操作完成后,必须给互斥量解锁,也就是前面所说的释放。这样其他等待该锁的线程才有机会获得该锁,否 则其他线程将会永远阻塞。
2、条件变量(conditions)
对线程进行条件限制,通俗的说,对某个线程进行限制,导致其阻塞不进行,直到条件不符合,唤醒线程
初始化:
条件变量的初始化也有两种方式,一种函数、一种宏
- 1
- 2
销毁:
- 1
线程挂起:
- 1
pthread_cond_t *restrict cond:定义的条件变量
pthread_mutex_t *restrict mutex:解锁操作
唤醒:
- 1
pthread_cond_t *cond:定义的条件变量
五、互斥量与信号量
互斥量:保护资源,线程互斥;一次只能有一个访问共享资源;初始值为1;互斥量要由获得锁的线程来释放(谁获得,谁释放)
信号量:可允许多个线程依次有序访问;初始值为0或1,取决于是计算信号量还是二值信号量;可以由其它线程释放
互斥量与信号量的区别
1、互斥量用于线程的互斥,信号量用于线程的同步
互斥:某一资源同时只允许一个访问者对其进行访问 无法限制访问者对资源的访问顺序 无序
同步: 通过其他机制 有序访问 多数情况下实现互斥 少数情况允许多个访问者同时访问资源
2、互斥量值只能为0/1,信号量值可以为非负整数
一个互斥量 一个资源互斥访问
信号量 多个同类资源的多线程互斥和同步
3、互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到