Linux 信号量之Posix基于内存的信号量
信号量(semaphore),也和互斥锁一样提供了线程间或者进程间的同步功能。
信号量有三种:
- Posix有名字的信号量
- Posix基于内存的信号量
- System V信号量
信号量比互斥锁高级,互斥锁只允许一个线程访问临界区,信号量可以多个,可以把信号量看作成互斥锁的升级版,但是如果能用互斥锁解决,就用互斥锁,互斥锁比信号量节省资源。
这篇文章只介绍Posix基于内存的信号量
1,单个生产者和单个消费者
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define NBUFF 10
int nitems;
struct {
int buff[NBUFF];
sem_t mutex, nempty, nstored;
} shared;
void* produce(void *args);
void* consume(void* args);
int main(int argc, char** argv){
pthread_t tid_produce, tid_consume;
if(argc != 2){
printf("usage error\n");
exit(1);
}
nitems = atoi(argv[1]);
//create 3 semaphore
sem_init(&shared.mutex, 0, 1);
sem_init(&shared.nempty, 0, NBUFF);
sem_init(&shared.nstored, 0, 0);
pthread_create(&tid_produce, NULL, produce, NULL);
pthread_create(&tid_consume, NULL, consume, NULL);
pthread_join(tid_produce, NULL);
pthread_join(tid_consume, NULL);
sem_destroy(&shared.mutex);
sem_destroy(&shared.nempty);
sem_destroy(&shared.nstored);
exit(0);
}
void* produce(void *args){
int i;
for(i = 0; i < nitems; ++i){
sem_wait(&shared.nempty);
sem_wait(&shared.mutex);
shared.buff[i % NBUFF] = i;
sem_post(&shared.mutex);
sem_post(&shared.nstored);
}
return NULL;
}
void* consume(void* args){
int i;
for(i = 0; i < nitems; ++i){
sem_wait(&shared.nstored);
sem_wait(&shared.mutex);
shared.buff[i % NBUFF] = i;
sem_post(&shared.mutex);
sem_post(&shared.nempty);
}
return NULL;
}
2,多个生产者和单个消费者
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define NBUFF 10
#define MAXTHRS 100
#define min(x,y) ( x > y ? y:x )
int nitems, nproducers;
struct {
int buff[NBUFF];
int idx;
int val;
sem_t mutex, nempty, nstored;
} shared;
void* produce(void *args);
void* consume(void* args);
int main(int argc, char** argv){
int i, count[MAXTHRS];
pthread_t tid_produce[MAXTHRS], tid_consume;
if(argc != 3){
printf("usage error\n");
exit(1);
}
nitems = atoi(argv[1]);
nproducers = min(atoi(argv[2]), MAXTHRS);
//create 3 semaphore
sem_init(&shared.mutex, 0, 1);
sem_init(&shared.nempty, 0, NBUFF);
sem_init(&shared.nstored, 0, 0);
for(i = 0; i < nproducers; ++i){
count[i] = 0;
pthread_create(&tid_produce[i], NULL, produce, &count[i]);
}
pthread_create(&tid_consume, NULL, consume, NULL);
for(i = 0; i < nproducers; ++i){
pthread_join(tid_produce[i], NULL);
printf("count[%d] = %d\n", i, count[i]);
}
pthread_join(tid_consume, NULL);
sem_destroy(&shared.mutex);
sem_destroy(&shared.nempty);
sem_destroy(&shared.nstored);
exit(0);
}
void* produce(void *arg){
int i;
for(i = 0; i < nitems; ++i){
sem_wait(&shared.nempty);
sem_wait(&shared.mutex);
if(shared.idx >= nitems){
sem_post(&shared.nempty);//注意点
sem_post(&shared.mutex);
return NULL;// all done
}
shared.buff[shared.idx % NBUFF] = shared.val;
shared.idx++;
shared.val++;
sem_post(&shared.mutex);
sem_post(&shared.nstored);
*((int*) arg) += 1;
}
return NULL;
}
void* consume(void* args){
int i;
for(i = 0; i < nitems; ++i){
sem_wait(&shared.nstored);
sem_wait(&shared.mutex);
if(shared.buff[i % NBUFF] != i){
printf("error:buff[%d] = %d\n", i, shared.buff[i % NBUFF]);
}
sem_post(&shared.mutex);
sem_post(&shared.nempty);
}
return NULL;
}
3,多个生产者和多个消费者
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define NBUFF 10
#define MAXTHRS 100
#define min(x,y) ( x > y ? y:x )
int nitems, nproducers, nconsumers;
struct {
int buff[NBUFF];
int idx;
int val;
int gidx;
int gval;
sem_t mutex, nempty, nstored;
} shared;
void* produce(void *args);
void* consume(void* args);
int main(int argc, char** argv){
int i, prodcount[MAXTHRS], conscount[MAXTHRS];
pthread_t tid_produce[MAXTHRS], tid_consume[MAXTHRS];
if(argc != 4){
printf("usage error\n");
exit(1);
}
nitems = atoi(argv[1]);
nproducers = min(atoi(argv[2]), MAXTHRS);
nconsumers = min(atoi(argv[3]), MAXTHRS);
//create 3 semaphore
sem_init(&shared.mutex, 0, 1);
sem_init(&shared.nempty, 0, NBUFF);
sem_init(&shared.nstored, 0, 0);
for(i = 0; i < nproducers; ++i){
prodcount[i] = 0;
pthread_create(&tid_produce[i], NULL, produce, &prodcount[i]);
}
for(i = 0; i < nconsumers; ++i){
conscount[i] = 0;
pthread_create(&tid_consume[i], NULL, consume, &conscount[i]);
}
for(i = 0; i < nproducers; ++i){
pthread_join(tid_produce[i], NULL);
printf("prodcount[%d] = %d\n", i, prodcount[i]);
}
for(i = 0; i < nconsumers; ++i){
pthread_join(tid_consume[i], NULL);
printf("conscount[%d] = %d\n", i, conscount[i]);
}
sem_destroy(&shared.mutex);
sem_destroy(&shared.nempty);
sem_destroy(&shared.nstored);
exit(0);
}
void* produce(void *arg){
int i;
for(i = 0; i < nitems; ++i){
sem_wait(&shared.nempty);
sem_wait(&shared.mutex);
if(shared.idx >= nitems){
sem_post(&shared.nstored);//注意点
sem_post(&shared.nempty);//注意点
sem_post(&shared.mutex);
return NULL;// all done
}
shared.buff[shared.idx % NBUFF] = shared.val;
shared.idx++;
shared.val++;
sem_post(&shared.mutex);
sem_post(&shared.nstored);
*((int*) arg) += 1;
}
return NULL;
}
void* consume(void* arg){
int i;
for(; ;){
sem_wait(&shared.nstored);
sem_wait(&shared.mutex);
if(shared.gidx >= nitems){
sem_post(&shared.nstored);//注意点
sem_post(&shared.mutex);
return NULL;// all done
}
i = shared.gidx % NBUFF;
if(shared.buff[i] != shared.gval){
printf("error:buff[%d] = %d\n", i, shared.buff[i]);
}
shared.gidx++;
shared.gval++;
sem_post(&shared.mutex);
sem_post(&shared.nempty);
*((int*) arg) += 1;
}
return NULL;
}
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
Linux 信号量之Posix基于内存的信号量的更多相关文章
- Linux 信号量之Posix有名字的信号量
信号量(semaphore),也和互斥锁一样提供了线程间或者进程间的同步功能. 信号量有三种: Posix有名字的信号量 Posix基于内存的信号量 System V信号量 信号量比互斥锁高级,互斥锁 ...
- linux第11天 共享内存和信号量
今天主要学习了共享内存和信号量 在此之前,有个管道问题 ls | grep a 整句话的意思是将ls输出到管道的写端,而流通到另一端的读端,grep a则是从管道的读端读取相关数据,再做筛选 共享内存 ...
- Linux进程同步之POSIX信号量
POSIX信号量是属于POSIX标准系统接口定义的实时扩展部分.在SUS(Single UNIX Specification)单一规范中,定义的XSI IPC中也同样定义了人们通常称为System V ...
- system V信号量和Posix信号量
一.函数上的区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量.它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线.例如,应该是sem ...
- 信号量(Posix)
Posix信号量分为有名信号量和无名信号量 1. Posix有名信号量 有名信号量既可以用于线程间的同步也可以用于进程间的同步 sem都是创建在/dev/shm目录下,名字格式sem.xxx,只需要指 ...
- 第三十三章 System V共享内存与信号量综合
用信号量解决生产者.消费者问题 实现shmfifo ip.h #ifndef _IPC_H #define _IPC_H #include <unistd.h> #include < ...
- linux网络编程-posix信号量与互斥锁(39)
-posix信号量信号量 是打开一个有名的信号量 sem_init是打开一个无名的信号量,无名信号量的销毁用sem_destroy sem_wait和sem_post是对信号量进行pv操作,既可以使用 ...
- Linux下用信号量实现对共享内存的访问保护
转自:http://www.cppblog.com/zjl-1026-2001/archive/2010/03/03/108768.html 最近一直在研究多进程间通过共享内存来实现通信的事情,以便高 ...
- Linux 内核同步之自旋锁与信号量的异同【转】
转自:http://blog.csdn.net/liuxd3000/article/details/8567070 Linux 设备驱动中必须解决的一个问题是多个进程对共享资源的并发访问,并发访问会导 ...
随机推荐
- ENVOIA
1,ENVOIA 组织架构讲解 2,开发中的各文件详细讲解 3,系统Data Model讲解 ENOVIA 2012 Online doc文档简介. 介绍ENOVIA组织架构. 介绍ENOVIA前身M ...
- Linux 修改/etc/sudoers 可被任何修改,如何解决
今天不小心,修改了/etc/sudoers的权限 改成了 777的权限, 于是每次使用sudo都会弹出 sudo:sudo /etc/sudoers is world writable sudo:no ...
- c# 第27节 结构、枚举
本节内容: 1:为什么要有结构 2:结构体的声明和使用 3:为什么要有枚举.常识大考验 4:枚举的声明 5:枚举的使用 6:枚举的各种转换 1:为什么要有结构 2:结构体的声明和使用 结构的声明位置: ...
- ioctl操作
在本书中有两个地方都对这个函数进行了介绍,其实还有很多地方需要这个函数.ioclt函数传统上一直作为纳西而不适合归入其他精细定义类别的特性的系统接口.网络程序(特别是服务器程序)经常在程序启动执行后使 ...
- linux虚拟机安装python 及 配置环境变量
一.安装anaconda 下载anaconda安装包 (wget -P filepath 下载链接) linux下安装anaconda教程,并添加清华镜像 sh Anaconda3-5.3.1-Lin ...
- USACO Corn Fields
洛谷 P1879 [USACO06NOV]玉米田Corn Fields 洛谷传送门 题目描述 Farmer John has purchased a lush new rectangular past ...
- Python else
Python else else 可以用来搭配其他语句完成条件判断 最常用的就是 if...else... 当然还有一些其他语句也可以配合 else 使用 if if...else... 是最简单的条 ...
- Python 基础排序算法
冒泡排序(bubble sort) 思路 以升序为例: 从第一个数开始向后两两对比,将大的数一直向后移动,直至最大的数移到最后,再找第二大的数 最好情况:O(n) 一般情况:O(n^2) 最坏情况:O ...
- jdbc工具类是多例的
一直以为他 是单例的, 以为创建个工具类就是为了单例, 节省效率 , 其实 是为了封装代码, 简洁 ! 还有重要一点 : 所欲工具类里面不要抛异常 要捕捉异常 !
- Zuul中聚合Swagger的坑
每个服务都有自己的接口,通过Swagger来管理接口文档.在服务较多的时候我们希望有一个统一的入口来进行文档的查看,这个时候可以在zuul中进行文档的聚合显示. 下面来看下具体的整合步骤以及采坑记录. ...