system v共享内存与信号量综合
ipc.h
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #ifndef _IPC_H_
#define _IPC_H_ union semun {
int val;
struct semid_ds *buf;
unsigned short *array; struct seminfo *_buf;
}; int sem_create(key_t key);
int sem_open(key_t key); int sem_p(int semid);
int sem_v(int semid);
int sem_d(int semid);
int sem_setval(int semid, int val);
int sem_getval(int semid);
int sem_getmode(int semid);
int sem_setmode(int semid, char* mode); #endif //_IPC_H_
ipc.c
#include "ipc.h" int sem_create(key_t key)
{
int semid = semget(key,, | IPC_CREAT | IPC_EXCL);
if (- == semid)
{
printf("sem create faild\n");
exit();
}
return semid;
}
int sem_open(key_t key)
{
int semid = semget(key,,);
if (- == semid)
{
printf("sem open faild\n");
exit();
}
return semid;
} int sem_p(int semid)
{
struct sembuf sb = {,-,};
int ret = semop(semid,&sb,);
if(- == ret)
{
printf("sem p faild\n");
exit();
}
return ret;
}
int sem_v(int semid)
{
struct sembuf sb = {,,};
int ret = semop(semid,&sb,);
if(- == ret)
{
printf("sem v faild\n");
exit();
}
return ret;
}
int sem_d(int semid)
{
int ret = semctl(semid, , IPC_RMID, );
return ret;
}
int sem_setval(int semid, int val)
{
union semun su;
su.val = val;
int ret = semctl(semid, , SETVAL,su);
if (- == ret)
{
printf("sem setval faild\n");
exit();
}
return ret;
}
int sem_getval(int semid)
{
int ret = semctl(semid, , GETVAL,);
if (- == ret)
{
printf("sem getval faild\n");
exit();
}
return ret;
}
int sem_getmode(int semid)
{
union semun su;
struct semid_ds sem;
su.buf = &sem;
int ret = semctl(semid , , IPC_STAT, su);
if (- == ret)
{
printf("sem getmode failed\n");
exit();
}
printf("current permissions is %o\n",su.buf->sem_perm.mode);
return ret;
}
int sem_setmode(int semid, char* mode)
{
union semun su;
struct semid_ds sem;
su.buf = &sem;
int ret = semctl(semid , , IPC_STAT, su);
if (- == ret)
{
printf("sem getmode failed\n");
exit();
}
printf("current permissions is %o\n",su.buf->sem_perm.mode);
sscanf(mode ,"%o",(unsigned int*)&su.buf->sem_perm.mode);
ret = semctl(semid , , IPC_STAT, su);
if (- == ret)
{
printf("sem getmode failed\n");
exit();
}
printf("permissios update...\n"); return ret;
}
shmfifo.h
#include "ipc.h" #ifndef _SHM_FIFO_H_
#define _SHM_FIFO_H_ typedef struct shmfifo shmfifo_t;
typedef struct shmhead shmhead_t; typedef struct stu
{
char name[];
int age;
}STU; struct shmhead
{
unsigned int blksize; // 块大小
unsigned int blocks; // 总块数
unsigned int rd_index; // 读索引
unsigned int wr_index; // 写索引
}; struct shmfifo
{
shmhead_t *p_shm; // 共享内存头部指针
char *p_payload; // 有效负载的起始地址 int shmid; // 共享内存ID
int sem_mutex; // 用来互斥用的信号量
int sem_full; // 用来控制共享内存是否满的信号量
int sem_empty; // 用来控制共享内存是否空的信号量
}; shmfifo_t* shmfifo_init(int key, int blksize, int blocks);//初始化
void shmfifo_put(shmfifo_t *fifo, const void *buf);//添加数据到环形缓冲区
void shmfifo_get(shmfifo_t *fifo, void *buf);//从缓冲区中取数据
void shmfifo_destroy(shmfifo_t *fifo);//释放共享内存的环形缓冲区 #endif /* _SHM_FIFO_H_ */
shmfifo.c
#include "shmfifo.h"
#include <assert.h> shmfifo_t* shmfifo_init(int key, int blksize, int blocks)
{
//分配内存空间
shmfifo_t *fifo = (shmfifo_t *)malloc(sizeof(shmfifo_t));
assert(fifo != NULL);
memset(fifo, , sizeof(shmfifo_t)); int shmid;
shmid = shmget(key, , );
int size = sizeof(shmhead_t) + blksize*blocks;
if (shmid == -)
{//创建共享内存
fifo->shmid = shmget(key, size, IPC_CREAT | );
if (fifo->shmid == -)
exit(); fifo->p_shm = (shmhead_t*)shmat(fifo->shmid, NULL, );
if (fifo->p_shm == (shmhead_t*)-)
exit(); fifo->p_payload = (char*)(fifo->p_shm + ); //进行字段初始化
fifo->p_shm->blksize = blksize;
fifo->p_shm->blocks = blocks;
fifo->p_shm->rd_index = ;
fifo->p_shm->wr_index = ; fifo->sem_mutex = sem_create(key);
fifo->sem_full = sem_create(key+);
fifo->sem_empty = sem_create(key+); sem_setval(fifo->sem_mutex, );
sem_setval(fifo->sem_full, blocks);
sem_setval(fifo->sem_empty, );
}
else
{//打开共享内存
fifo->shmid = shmid;
fifo->p_shm = (shmhead_t*)shmat(fifo->shmid, NULL, );
if (fifo->p_shm == (shmhead_t*)-)
exit(); fifo->p_payload = (char*)(fifo->p_shm + ); fifo->sem_mutex = sem_open(key);
fifo->sem_full = sem_open(key+);
fifo->sem_empty = sem_open(key+);
} return fifo;
} void shmfifo_put(shmfifo_t *fifo, const void *buf)
{
sem_p(fifo->sem_full);
sem_p(fifo->sem_mutex); //生产产品
memcpy(fifo->p_payload+fifo->p_shm->blksize*fifo->p_shm->wr_index,
buf, fifo->p_shm->blksize);
fifo->p_shm->wr_index = (fifo->p_shm->wr_index + ) % fifo->p_shm->blocks; sem_v(fifo->sem_mutex);
sem_v(fifo->sem_empty);
} void shmfifo_get(shmfifo_t *fifo, void *buf)
{
sem_p(fifo->sem_empty);
sem_p(fifo->sem_mutex); memcpy(buf, fifo->p_payload+fifo->p_shm->blksize*fifo->p_shm->rd_index,
fifo->p_shm->blksize);
fifo->p_shm->rd_index = (fifo->p_shm->rd_index + ) % fifo->p_shm->blocks;
sem_v(fifo->sem_mutex);
sem_v(fifo->sem_full);
} void shmfifo_destroy(shmfifo_t *fifo)
{
//删除创建的信息量集
sem_d(fifo->sem_mutex);
sem_d(fifo->sem_full);
sem_d(fifo->sem_empty); //删除共享内存
shmdt(fifo->p_shm);//删除共享内存头部
shmctl(fifo->shmid, IPC_RMID, );//删除整个共享内存 //释放fifo的内存
free(fifo);
}
shmfifo_send.c
#include "shmfifo.h"
/*
typedef struct stu
{
char name[32];
int age;
}STU;
*/
int main(void)
{
shmfifo_t *fifo = shmfifo_init(,sizeof(STU),); STU s;
memset(&s, , sizeof(STU));
s.name[] = 'A';
int i;
for(i=;i<;i++)
{
s.age = + i;
shmfifo_put(fifo,&s);
s.name[] = s.name[] + ;
printf("send ok\n");
}
return ;
}
shmfifo_recv.c
#include "shmfifo.h"
/*
typedef struct stu
{
char name[32];
int age;
}STU;
*/
int main(void)
{
shmfifo_t *fifo = shmfifo_init(,sizeof(STU),); STU s;
memset(&s, , sizeof(STU)); int i;
for(i=;i<;i++)
{
shmfifo_get(fifo,&s);
printf("name = %s, age = %d\n",s.name,s.age);
}
return ;
}
shmfifo_free.c
#include "shmfifo.h" int main(void)
{
shmfifo_t *fifo = shmfifo_init(,sizeof(STU),);
shmfifo_destroy(fifo);
return ;
}
Makefile
.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN= shmfifo_send shmfifo_recv shmfifo_free
OBJS1=shmfifo_send.o shmfifo.o ipc.o
OBJS2=shmfifo_recv.o shmfifo.o ipc.o
OBJS3=shmfifo_free.o shmfifo.o ipc.o
all:$(BIN)
%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
shmfifo_send:$(OBJS1)
$(CC) $(CFLAGS) $^ -o $@
shmfifo_recv:$(OBJS2)
$(CC) $(CFLAGS) $^ -o $@
shmfifo_free:$(OBJS3)
$(CC) $(CFLAGS) $^ -o $@ clean:
rm -f *.o $(BIN)
system v共享内存与信号量综合的更多相关文章
- 第三十三章 System V共享内存与信号量综合
用信号量解决生产者.消费者问题 实现shmfifo ip.h #ifndef _IPC_H #define _IPC_H #include <unistd.h> #include < ...
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
- 阐述linux IPC(五岁以下儿童):system V共享内存
[版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途] system V共享内存和posix ...
- php进程(线程)通信基础--System V共享内存
PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项 System V消息,--enable-sysvmsg System V信号量支持,--enable-sysvsem ...
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- System V共享内存
目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...
- UNIX环境高级编程——System V 共享内存区
共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...
- Linux IPC实践(9) --System V共享内存
共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...
- System V 共享内存区
1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...
随机推荐
- 剑指offer-栈的压入与弹出
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序 ...
- 四、触发器(Trigger)
一.触发器 有点类似AOP里的拦截器,触发器不能传递参数,也不能输出参数,也不能显式调用,只有当满足触发器条件的时候Oracle会自动调用. 触发器: 1.语句级别的触发器:CRUD操作 2.行级别的 ...
- MYSQL--三大范式
MYSQL--三大范式 范式简介: 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小.目前关系数据库有六 ...
- oracle 分组查询
常用的函数: ·:统计个数:COUNT(),根据表中的实际数据量返回结果: ·:求和:SUM(),是针对于数字的统计,求和 ·:平均值 ...
- Mysql for Linux安装配置之—— rpm(bundle)安装
1.准备及安装1)下载rpm安装包(或rpm bundle) rpm安装包包括两个(bundle会更多),一个是client,另一个是server,例如:MySQL-client-5.5.44-1. ...
- socket简述-------转载
“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...
- python---多线程与多进程
一. 单进程多线程 1. 使用的模块是Threading.使用join()函数进行阻塞. from pdf2txt import pdfTotxt1, pdfTotxt2 import xlrd im ...
- loaclStorage、sessionStorage
这里需要注意的是这两种储存方式只能以字符串的形式来存取 html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage.sessionStorage用于 ...
- 我眼中的Linux系统和红帽RHCE认证
牛顿曾经说过“我不知道在别人看来,我是什么样的人:但在我自己看来,我不过就象是一个在海滨玩耍的小孩,为不时发现比寻常更为光滑的一块卵石或比寻常更为美丽的一片贝壳而沾沾自喜,而对于展现在我面前的浩瀚的真 ...
- 读书笔记 C# 接口之浅析
一.接口可以包含 属性.方法.事件和索引器: 二.接口不能被实例化: 三.一个类可以继承多个接口: 四.接口不能包含方法的实现: 五.继承接口的类必须实现接口中所有成员: 六.显式实现接口的成员,不能 ...