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中的一个文 ...
随机推荐
- oracle中给表和列起别名
SELECT xxmc,sname as xsxm,sex,phone,address jzdz FROM student s LEFT JOIN xxjbxx x ON x.sid = s.sid ...
- Eclipse直接打开类文件/文件夹所在的本地目录
1.Eclipse原生的文件浏览操作 选择项目目录/文件 按 ALT+SHIFT +W , 会弹出菜单点击 System Explorer 就可以打开文件所在的本地目录了: 设置工具目录 Run -- ...
- python模块安装注意事项
在安装python的第三方模块时,需要注意路径问题. 1.如果python是按默认位置安装的,则可以直接在命令提示符中进行安装,即pip install module_name. 2.如果python ...
- Intersecting Lines
Intersecting Lines We all know that a pair of distinct points on a plane defines a line and that a p ...
- 水题系列二:PhoneNumbers
问题描述: Phonenumbers 企业喜欢用容易被记住的电话号码.让电话号码容易被记住的一个办法是将它写成一 个容易记 住的 单词或 者短语 .例如 ,你 需要给 滑铁卢 大学打 电话时 ,可 以 ...
- 更改pip源至国内镜像
更改pip源至国内镜像 经常在使用Python的时候需要安装各种模块,而pip是很强大的模块安装工具,但是由于国外官方pypi经常被墙,导致不可用,所以我们最好是将自己使用的pip源更换一下,这样 ...
- ASP.Net MVC(4) 之js css引用与压缩
资源引用 可以用即可以直接使用“~”来表示根目录. 引入js <script src="~/Areas/OrderManage/JS/Form.js"></scr ...
- web技术栈中不可或缺的Linux技术
Web技术最重要的载体便是服务器,服务器运行在公共的网络环境下,为广大的用户提供网页浏览.信息通讯.消息推送等服务,从最开始的硬件服务器到虚拟主机技术,再到虚拟化技术的出现和云概念的兴起,绝大部分都是 ...
- python 学习笔记 字符串和编码
字符编码:因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理,最早的计算机在设计时采用8个比特(bit)作为一个字节 (byte),所以,一个字节能表示的最大的整数是255(二进 ...
- linux图形和命令界面切换
一.系统不在虚拟机中的情况 使用ctrl+alt+F1~6切换到命令行界面:ctrl+alt+F7切换到图形界面 二.系统在虚拟机中的情况 Ctrl+Alt+shift+F1~6切换到命令行界面:使用 ...