线程同步、信号量、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 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...
随机推荐
- CF #319 div 2 E
在一个边长为10^6正方形中,可以把它x轴分段,分成1000段.奇数的时候由底往上扫描,偶数的时候由上往下扫描.估计一下这个最长的长度,首先,我们知道有10^6个点,则y邮方向最多移动10^3*10^ ...
- HDU 4544
贪心算法+优先队列. 很明显是应当先消灭blood值大的,那么注意到,对于少blood值的,能灭大blood值的箭必定能消灭小blood值的,所以,可以先排序,在消灭一个blood值的时候,选择一个小 ...
- swift 雨燕 新手教程
Apple Swift编程语言新手教程 chox 2014-06-03 文件夹 简单介绍 入门 简单值 控制流 函数与闭包 对象与类 枚举与结构 1 简单介绍 今天凌晨Apple刚刚公布了Swif ...
- HDU 4099 Revenge of Fibonacci Trie+高精度
Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: ...
- yum install mysql(转载)
linux下使用yum安装mysql 1.安装查看有没有安装过: yum list installed mysql* rpm -qa | grep mysql* 查 ...
- 辨异 —— Java 中 String 的相等性比较
How do I compare strings in Java? 1. 语法知识 ==:判断的是引用的相等性(reference equality),也即是否为同一对象: .equals():判断的 ...
- CPPCMS库在Windows下的使用
标题:CPPCMS库在Windows下的使用时间:2012-7作者:Kagula 环境:[1]WinXP SP3[2]VisualStudio2008 SP1[3]ZLib 1.2.7[4]PCRE ...
- codeforces round #424 div2
A 暴力查询,分三段查就可以了 #include<bits/stdc++.h> using namespace std; ; int n, pos; int a[N]; int main( ...
- java jdk 管理工具
官网:http://www.jenv.be/ 安装: Linux / OS X $ git clone https://github.com/gcuisinier/jenv.git ~/.jenv M ...
- selenium3 + python - table定位
前言 在web页面中经常会遇到table表格,特别是后台操作页面比较常见.本篇详细讲解table表格如何定位. 一.认识table 1.首先看下table长什么样,如下图,这种网状表格的都是table ...