- 一、信号量
- 信号量是一种用于线程间或进程间同步的机制,它可以用来控制对共享资源的访问,协调线程的执行顺序
- 线程间同步机制:让多个线程在执行某个任务时,具有先后顺序的执行
- 信号量的基本概念
- 信号量是一个整型变量,支持两种原子操作:
- P操作(wait):尝试获取信号量,如果信号量值>0则减1并继续,否则阻塞
- V操作(post):释放信号量,将信号量值加1并唤醒等待的线程
- 操作步骤:头文件include<semaphore.h>
- 定义信号量对象
- sem_t
- 初始化信号量
- int sem_init(sem_t *sem, int pshared, unsigned int value);
- 功能:初始化信号量
- 参数:sem:要初始化的信号量的地址(指针);pshared:0表示线程间共享,非0表示进程间共享;value:信号量的初始值(0/1)
- 返回值:成功:0;失败-1
- int sem_init(sem_t *sem, int pshared, unsigned int value);
- 申请信号量:P操作
- int sem_wait(sem_t *sem);
- 释放信号量:V操作
- int sem_post(sem_t *sem);
- 销毁信号量
- int sem_destroy(sem_t *sem);
- 定义信号量对象
- 二、死锁
- 在多线程编程中,当需要同时获取多个锁时,不正确的加锁顺序可能导致死锁。死锁是指两个或多个线程互相等待对方持有的锁,导致所有线程都无法继续执行的情况
- 死锁的四个必要条件
- 互斥条件:资源一次只能由一个线程持有
- 请求与保持条件:线程持有至少一个资源,并等待获取其他资源
- 不剥夺条件:已分配给线程的资源不能被其他线程强行夺取
- 循环等待条件:存在一个线程的循环链,每个线程都在等待下一个线程所持有的资源
- 解决方法
- 1.锁一定要成对出现
- 2.使线程的加锁顺序一致
- 3.破坏环路等待条件
- 使用非阻塞锁,一旦线程发现请求的锁被使用,就去释放自己拥有的锁
- pthread_mutex_trylock();
- int sem_trywait(sem_t *sem)
- 三、进程间通信:IPC机制
- 进程间通信是指在不同进程之间传递数据或信号的机制
- 同一主机进程间通信
- 无名管道(pipe)
- 只能用于同一主机具有亲缘关系的进程间的通信(父子进程)
- 操作流程
- 创建无名管道:pipe()
- pipefd[0]---->读端
- pipefd[1]---->写端
- 写管道---->write
- 读管道---->read
- 关闭管道---->close
- 创建无名管道:pipe()
- 无名管道默认大小:65536bytes=64K
- 管道的特性:
- 写阻塞:读端和写端都存在,向管道中写数据,当管道满时,发生写阻塞
- 读阻塞:读端和写端都存在,从管道中读数据,若管道为空,则发生读阻塞
- 读返回0:当写端关闭,从管道中读数据,若管道中有数据,则读到数据;若管道中没有数据,read则返回0,不再阻塞
- 管道破裂:读端关闭,向管道中写入数据,发生管道破裂(异常)
- 有名管道(FIFO)
- 可以用于同一主机任意进程间通信
- 通过文件系统中的特殊文件访问
- 操作流程:
- 创建管道文件:mkfifo()
- int mkfifo(const char *pathname, mode_t mode)
- 功能:创建一个管道文件
- 参数:pathname:管道文件的名称;mode:管道文件的读写执行权限
- 返回值:成功:0;失败-1
- int mkfifo(const char *pathname, mode_t mode)
- 打开管道文件:open()
- 写管道文件:write()
- 读管道文件:read()
- 关闭管道文件:close()
- 删除管道文件:remove()
- intremove(const char*pathname)
- 创建管道文件:mkfifo()
- 信号量
- 共享内存
- 消息队列
- 信号量集
- 无名管道(pipe)
- 在不同主机进程间通信
- socket通信
- 网络通信
信号量、死锁、管道
最新推荐文章于 2025-08-19 16:14:16 发布