线程同步、信号量、system v IPC
一、线程同步
条件变量
什么是条件变量?
线程A等待某个条件成立,条件成立,线程A才继续向下执行。线程B的执行使条件成立,条件成立以后唤醒线程A,以继续执行。这个条件就是条件变量。
pthread_cond_t 类型 就是条件变量的类型
对类型的封装如下:
#include <pthread.h>
//条件变量的静态初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_cond_init(pthread_cond_t *cond,\ pthread_condattr_t *cond_attr);
功能:初始化一个条件变量
参数:
cond:指定要初始化的条件变量
cond_attr:NULL 默认属性
返回值:
成功
非0 错误 int pthread_cond_signal(pthread_cond_t *cond);
功能:启动在等待条件变量变为真的一个线程
参数:
cond:指定条件变量
返回值:
成功
非0 错误 int pthread_cond_broadcast(pthread_cond_t *cond);
功能:启动所有的等待条件变量为真的线程
参数:
cond:指定条件变量
返回值:
成功
非0 错误 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
功能:等待条件变量为真
参数:
cond:指定等待的条件变量
mutex:等待之前需要解开的锁
返回值:
成功
非0 错误 操作步骤:
、先原子解mutex锁。
、让线程等待条件变量变为真。
、条件变量为真的时候,加锁 int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex, \
const struct timespec *abstime);
功能:超时等待,超时返回错误
参数:
cond:指定等待的条件变量
mutex:等待之前需要解开的锁
abstime:指定等待的时间
返回值:
成功
非0 错误
int pthread_cond_destroy(pthread_cond_t *cond);
功能:销毁条件变量
参数:
cond:指定要销毁的条件变量
返回值:
成功
非0 错误 生产者和消费者的例子
链表实现 生产者生产出来对象放到链表的头部
消费者从链表的头部取出消费。
第一思考:两个线程如何同步访问链表的头部
第二思考:如果链表为空,消费者等待生产者线程生产对象。
第三思考:生产者线程,生产出对象通知消费者。 代码参见: cond.c 信号量
多个线程使用多个资源的时候,使用信号量实现线程的同步。
sem_t类型
类型的操作如下:
sem_init()
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化信号量
参数:
sem:指定了要初始化的信号量
pshared: 应用于多线程 非0 多进程
value:指定了信号量的初始值
返回值:
成功
- 失败 errno被设置 sem_destroy()
#include <semaphore.h>
int sem_destroy(sem_t *sem);
功能:销毁信号量
参数:
sem:指定要销毁的信号量
返回值:
成功
- 错误 errno被设置 sem_post()
#include <semaphore.h>
int sem_post(sem_t *sem);
功能:信号量的值加1操作
参数:
sem:指定的信号量,就是这个信号量的值加1.
返回值:
成功
- 错误 errno被设置 sem_wait()
#include <semaphore.h>
int sem_wait(sem_t *sem);
功能:信号量的值减1.如果信号量的值为0.阻塞等待
参数:
sem:指定了要操作的信号量
返回值:
成功
- 错误 errno被设置
int sem_trywait(sem_t *sem); int sem_timedwait(sem_t *sem, \
const struct timespec *abs_timeout); 使用信号量,实现生产者和消费者的例子
使用环状队列实现。
代码参见 sem.c 线程结束了 二、system v IPC
信号量集
信号量集就是数组,数组里的每一个元素都是信号量类型的。 、先获取键值
ftok()
、使用键值获取信号量集的id
semget()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
功能:获取信号量集的id
参数:
key:ftok()的返回值
nsems:指定了信号量集中的元素个数
semflg:
IPC_CREAT:
IPC_EXCL:
mode:指定信号量集的权限
返回值:
非负整数,是信号量集的id。
- 错误 errno被设置 、设置信号量集中的信号量的初值或者获取信号量的值。
semctl()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
功能:信号量的控制操作
参数:
semid:指定了信号量集
semnum:指定了信号量在数组中的下标
cmd:指定了对信号量的控制操作命令
GETVAL:获取到第几个信号了的semval值。 semval的值
SETVAL:设置第几个信号量的semval值为arg.val。 ...:可变参数。这个有没有,什么类型?取决于cmd。
返回值:
- 错误 errno被设置 需要自定义
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT,IPC_SET */
unsigned short *array; /*Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
}; 、对指定的信号量加法或者减法操作
semop()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);
功能:信号量操作
参数:
semid:指定了信号量集
sops:指定了对某个信号量的具体操作
nsops:指定了要操作的信号量的个数。 返回值:
成功
- 错误 errno被设置 操作定义在这个结构体中
struct sembuf{
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */ };
sem_flg:
IPC_NOWAIT
IPC_UNDONE 自动撤销操作 sem_num:指定了要操作的信号量在数组的下标
sem_op:指定了操作的类型
操作类型分为3种
> semval+sem_op semval做加法
= <:
semval>sem_op的绝对值,这个操作立即执行。 semval<sem_op的绝对值
申请的资源数>可用资源数 IPC_NOWAIT 非阻塞
sem_flg= 阻塞等待资源可用 举例说明 使用信号量集实现进程间的通讯。
两个进程
PA.c 设置信号量的值 ,每隔3秒,semval的值减1
Pb.c 每隔1秒,获取信号量的值,
线程同步、信号量、system v IPC的更多相关文章
- System V IPC 之信号量
本文继<System V IPC 之共享内存>之后接着介绍 System V IPC 的信号量编程.在开始正式的内容前让我们先概要的了解一下 Linux 中信号量的分类. 信号量的分类 在 ...
- Linux 系统编程 学习:04-进程间通信2:System V IPC(1)
Linux 系统编程 学习:04-进程间通信2:System V IPC(1) 背景 上一讲 进程间通信:Unix IPC-信号中,我们介绍了Unix IPC中有关信号的概念,以及如何使用. IPC的 ...
- Linux 系统编程 学习:05-进程间通信2:System V IPC(2)
Linux 系统编程 学习:05-进程间通信2:System V IPC(2) 背景 上一讲 进程间通信:System V IPC(1)中,我们介绍了System IPC中有关消息队列.共享内存的概念 ...
- System V IPC 之共享内存
IPC 是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行系列操作的一组机制: 通过信号量与其他进程进行同步 向其他进程发送消息或者从其他进程接收消息 ...
- UNIX 进程间通讯(IPC)概念(Posix,System V IPC)
IPC(Inter-Process Communication,进程间通讯)可以有三种信息共享方式(随文件系统,随内核,随共享内存).(当然这里虽然说是进程间通讯,其实也是可以和线程相通的). 相对 ...
- 第3章 System V IPC
3.1 概述 System V IPC 包含:System V消息队列.System V信号量.System V共享内存. 3.2 key_t 键和 ftok函数 这三种类型的System V IPC ...
- 《Unix网络编程》卷2 读书笔记 第3章- System V IPC
1. 概述 三种类型的System V IPC:System V 消息队列.System V 信号量.System V 共享内存区 System V IPC在访问它们的函数和内核为它们维护的信息上共享 ...
- 从并发处理谈PHP进程间通信(二)System V IPC
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- System V IPC 之消息队列
消息队列和共享内存.信号量一样,同属 System V IPC 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...
随机推荐
- 软件测试之怎么避免Bug漏测?
一.对需求评审阶段,对业务需求细节理解不明确,未深入挖掘隐含拓展需求 改进措施 需求评审前,我们应该先仔细阅读prd及交互文档,先形成自己对产品的思考,通过脑图的方式列出对产品设计的疑问点,从用户或者 ...
- POJ2584_T-Shirt Gumbo(二分图多重最大匹配/最大流)
解题报告 http://blog.csdn.net/juncoder/article/details/38239367 题目传送门 题意: X个參赛选手,每一个选手有衣服大小的范围,5种大小的队服,求 ...
- jQuery EasyUI 1.4更新记录
问题: menu:修复当删除一个menu项时.menu高度不准确. datagrid:修复当datagrid宽度太小时,fitColumns方法不能使用. 改进: 1.为easyui全部组件新增了自适 ...
- Geeks - Detect Cycle in a Directed Graph 推断图是否有环
Detect Cycle in a Directed Graph 推断一个图是否有环,有环图例如以下: 这里唯一注意的就是,这是个有向图, 边组成一个环,不一定成环,由于方向能够不一致. 这里就是添加 ...
- 64位BASM学习随笔(一)
64位BASM学习随笔(一) Delphi的BASM一直是我最喜爱的内嵌汇编语言,同C/C++的内联汇编相比,它更方便,更具灵活性,由于C/C++的内联汇编仅仅能是或插入式的汇编代码,函数花括号 ...
- STL_算法_逆转(reverse,reverse_copy)
C++ Primer 学习中.. . 简单记录下我的学习过程 (代码为主) //全部容器适用 reverse(b,e) //逆转区间数据 reverse_copy(b,e,b2) /** ...
- 学习笔记——DISTINCT
DISTINCT印象中向来被人诟病,说它效率低下.但网上那些SQL 面试题答案,却时有用之.其中 COUNT(DISTINCT 句式,我以前很少用,这里做个笔记. 为管理岗位业务培训信息,建立3个表: ...
- 【POJ 2442】 Sequence
[题目链接] http://poj.org/problem?id=2442 [算法] 堆 [代码] #include <algorithm> #include <bitset> ...
- B1391 [Ceoi2008]order 最大权闭合图 最小割
啊啊啊,假的题吧!!!我用的当前弧优化T了6个点,其他人不用优化AC!!!震惊!!!当前弧优化是假的吧!!! 到现在我也没调出来...大家帮我看看为啥70.... 来讲一下这个题的思路,就是设一个源点 ...
- fopen文件目录问题
程序当前目录下.如果是在 VC 里面运行的, 这个目录是工程的目录. 如果是双击 exe 运行的, 这个目录就是 exe 所在的目录.