线程同步、信号量、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 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...
随机推荐
- [Debug] Use Remote Sources to Debug a Web App on an Emulator, Simulator, or Physical Device
We can emulate different operating systems, browsers, and devices within a desktop operating system. ...
- HDOJ题目3440 House Man(差分约束)
House Man Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- compact处理流程分析
compact处理流程分析 compact的处理与split同样.由client端与flush时检查发起. 针对compact另一个在rs生成时生成的CompactionChecker线程定期去检查是 ...
- Codeforces--630J--Divisibility(公倍数)
J - Divisibility Crawling in process... Crawling failed Time Limit:500MS Memory Limit:65536KB ...
- 267C
二分+高斯消元 我们利用物理里的势能来表示,每个点有一个势能h,再由流量守恒可以得到deg[x]*h[x]=sigma(h[y]) 如果x,y之间有边.这个式子是由流量守恒推出的,所以当x=1或n是不 ...
- runC爆严重安全漏洞,主机可被攻击!使用容器的快打补丁
runC 是 Docker,Kubernetes 等依赖容器的应用程序的底层容器运行时.此次爆出的严重安全漏洞可使攻击者以 root 身份在主机上执行任何命令. 容器的安全性一直是容器技术的一个短板. ...
- thymeleaf公共页面元素抽取
1.抽取公共片段 使用thymeleaf的th:fragment为样抽取的公共片段命名, 如下把div标签命名为 copy,就可以获取到div整个里的内容<div th:fragment=&qu ...
- 海量数据统计topK
有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M.返回频数最高的100个词. 思路: 把这1G的数据一次性全部读入内存是不可能了,可以每次读一行,然后将该词存到 ...
- Cracking the Coding Interview 8.5
Implement an algorithm to print all valid combinations of n-pairs of parentheses #include<stdio.h ...
- SnackDown Online Qualifier 2017
好久没做题了,然后就想着随便做一个.无奈cf都是晚上,然后就看见这个,随便做做. 资格赛,只要做出来1题就行了,4天的时间. 1. 水题 #include <iostream> #incl ...