ipc.h

  1. #include <sys/types.h>
  2. #include <unistd.h>
  3. #include <sys/ipc.h>
  4. #include <sys/sem.h>
  5. #include <sys/shm.h>
  6. #include <errno.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. #ifndef _IPC_H_
  12. #define _IPC_H_
  13.  
  14. union semun {
  15. int val;
  16. struct semid_ds *buf;
  17. unsigned short *array;
  18.  
  19. struct seminfo *_buf;
  20. };
  21.  
  22. int sem_create(key_t key);
  23. int sem_open(key_t key);
  24.  
  25. int sem_p(int semid);
  26. int sem_v(int semid);
  27. int sem_d(int semid);
  28. int sem_setval(int semid, int val);
  29. int sem_getval(int semid);
  30. int sem_getmode(int semid);
  31. int sem_setmode(int semid, char* mode);
  32.  
  33. #endif //_IPC_H_

ipc.c

  1. #include "ipc.h"
  2.  
  3. int sem_create(key_t key)
  4. {
  5. int semid = semget(key,, | IPC_CREAT | IPC_EXCL);
  6. if (- == semid)
  7. {
  8. printf("sem create faild\n");
  9. exit();
  10. }
  11. return semid;
  12. }
  13. int sem_open(key_t key)
  14. {
  15. int semid = semget(key,,);
  16. if (- == semid)
  17. {
  18. printf("sem open faild\n");
  19. exit();
  20. }
  21. return semid;
  22. }
  23.  
  24. int sem_p(int semid)
  25. {
  26. struct sembuf sb = {,-,};
  27. int ret = semop(semid,&sb,);
  28. if(- == ret)
  29. {
  30. printf("sem p faild\n");
  31. exit();
  32. }
  33. return ret;
  34. }
  35. int sem_v(int semid)
  36. {
  37. struct sembuf sb = {,,};
  38. int ret = semop(semid,&sb,);
  39. if(- == ret)
  40. {
  41. printf("sem v faild\n");
  42. exit();
  43. }
  44. return ret;
  45. }
  46. int sem_d(int semid)
  47. {
  48. int ret = semctl(semid, , IPC_RMID, );
  49. return ret;
  50. }
  51. int sem_setval(int semid, int val)
  52. {
  53. union semun su;
  54. su.val = val;
  55. int ret = semctl(semid, , SETVAL,su);
  56. if (- == ret)
  57. {
  58. printf("sem setval faild\n");
  59. exit();
  60. }
  61. return ret;
  62. }
  63. int sem_getval(int semid)
  64. {
  65. int ret = semctl(semid, , GETVAL,);
  66. if (- == ret)
  67. {
  68. printf("sem getval faild\n");
  69. exit();
  70. }
  71. return ret;
  72. }
  73. int sem_getmode(int semid)
  74. {
  75. union semun su;
  76. struct semid_ds sem;
  77. su.buf = &sem;
  78. int ret = semctl(semid , , IPC_STAT, su);
  79. if (- == ret)
  80. {
  81. printf("sem getmode failed\n");
  82. exit();
  83. }
  84. printf("current permissions is %o\n",su.buf->sem_perm.mode);
  85. return ret;
  86. }
  87. int sem_setmode(int semid, char* mode)
  88. {
  89. union semun su;
  90. struct semid_ds sem;
  91. su.buf = &sem;
  92. int ret = semctl(semid , , IPC_STAT, su);
  93. if (- == ret)
  94. {
  95. printf("sem getmode failed\n");
  96. exit();
  97. }
  98. printf("current permissions is %o\n",su.buf->sem_perm.mode);
  99. sscanf(mode ,"%o",(unsigned int*)&su.buf->sem_perm.mode);
  100. ret = semctl(semid , , IPC_STAT, su);
  101. if (- == ret)
  102. {
  103. printf("sem getmode failed\n");
  104. exit();
  105. }
  106. printf("permissios update...\n");
  107.  
  108. return ret;
  109. }

shmfifo.h

  1. #include "ipc.h"
  2.  
  3. #ifndef _SHM_FIFO_H_
  4. #define _SHM_FIFO_H_
  5.  
  6. typedef struct shmfifo shmfifo_t;
  7. typedef struct shmhead shmhead_t;
  8.  
  9. typedef struct stu
  10. {
  11. char name[];
  12. int age;
  13. }STU;
  14.  
  15. struct shmhead
  16. {
  17. unsigned int blksize; // 块大小
  18. unsigned int blocks; // 总块数
  19. unsigned int rd_index; // 读索引
  20. unsigned int wr_index; // 写索引
  21. };
  22.  
  23. struct shmfifo
  24. {
  25. shmhead_t *p_shm; // 共享内存头部指针
  26. char *p_payload; // 有效负载的起始地址
  27.  
  28. int shmid; // 共享内存ID
  29. int sem_mutex; // 用来互斥用的信号量
  30. int sem_full; // 用来控制共享内存是否满的信号量
  31. int sem_empty; // 用来控制共享内存是否空的信号量
  32. };
  33.  
  34. shmfifo_t* shmfifo_init(int key, int blksize, int blocks);//初始化
  35. void shmfifo_put(shmfifo_t *fifo, const void *buf);//添加数据到环形缓冲区
  36. void shmfifo_get(shmfifo_t *fifo, void *buf);//从缓冲区中取数据
  37. void shmfifo_destroy(shmfifo_t *fifo);//释放共享内存的环形缓冲区
  38.  
  39. #endif /* _SHM_FIFO_H_ */

shmfifo.c

  1. #include "shmfifo.h"
  2. #include <assert.h>
  3.  
  4. shmfifo_t* shmfifo_init(int key, int blksize, int blocks)
  5. {
  6. //分配内存空间
  7. shmfifo_t *fifo = (shmfifo_t *)malloc(sizeof(shmfifo_t));
  8. assert(fifo != NULL);
  9. memset(fifo, , sizeof(shmfifo_t));
  10.  
  11. int shmid;
  12. shmid = shmget(key, , );
  13. int size = sizeof(shmhead_t) + blksize*blocks;
  14. if (shmid == -)
  15. {//创建共享内存
  16. fifo->shmid = shmget(key, size, IPC_CREAT | );
  17. if (fifo->shmid == -)
  18. exit();
  19.  
  20. fifo->p_shm = (shmhead_t*)shmat(fifo->shmid, NULL, );
  21. if (fifo->p_shm == (shmhead_t*)-)
  22. exit();
  23.  
  24. fifo->p_payload = (char*)(fifo->p_shm + );
  25.  
  26. //进行字段初始化
  27. fifo->p_shm->blksize = blksize;
  28. fifo->p_shm->blocks = blocks;
  29. fifo->p_shm->rd_index = ;
  30. fifo->p_shm->wr_index = ;
  31.  
  32. fifo->sem_mutex = sem_create(key);
  33. fifo->sem_full = sem_create(key+);
  34. fifo->sem_empty = sem_create(key+);
  35.  
  36. sem_setval(fifo->sem_mutex, );
  37. sem_setval(fifo->sem_full, blocks);
  38. sem_setval(fifo->sem_empty, );
  39. }
  40. else
  41. {//打开共享内存
  42. fifo->shmid = shmid;
  43. fifo->p_shm = (shmhead_t*)shmat(fifo->shmid, NULL, );
  44. if (fifo->p_shm == (shmhead_t*)-)
  45. exit();
  46.  
  47. fifo->p_payload = (char*)(fifo->p_shm + );
  48.  
  49. fifo->sem_mutex = sem_open(key);
  50. fifo->sem_full = sem_open(key+);
  51. fifo->sem_empty = sem_open(key+);
  52. }
  53.  
  54. return fifo;
  55. }
  56.  
  57. void shmfifo_put(shmfifo_t *fifo, const void *buf)
  58. {
  59. sem_p(fifo->sem_full);
  60. sem_p(fifo->sem_mutex);
  61.  
  62. //生产产品
  63. memcpy(fifo->p_payload+fifo->p_shm->blksize*fifo->p_shm->wr_index,
  64. buf, fifo->p_shm->blksize);
  65. fifo->p_shm->wr_index = (fifo->p_shm->wr_index + ) % fifo->p_shm->blocks;
  66.  
  67. sem_v(fifo->sem_mutex);
  68. sem_v(fifo->sem_empty);
  69. }
  70.  
  71. void shmfifo_get(shmfifo_t *fifo, void *buf)
  72. {
  73. sem_p(fifo->sem_empty);
  74. sem_p(fifo->sem_mutex);
  75.  
  76. memcpy(buf, fifo->p_payload+fifo->p_shm->blksize*fifo->p_shm->rd_index,
  77. fifo->p_shm->blksize);
  78. fifo->p_shm->rd_index = (fifo->p_shm->rd_index + ) % fifo->p_shm->blocks;
  79. sem_v(fifo->sem_mutex);
  80. sem_v(fifo->sem_full);
  81. }
  82.  
  83. void shmfifo_destroy(shmfifo_t *fifo)
  84. {
  85. //删除创建的信息量集
  86. sem_d(fifo->sem_mutex);
  87. sem_d(fifo->sem_full);
  88. sem_d(fifo->sem_empty);
  89.  
  90. //删除共享内存
  91. shmdt(fifo->p_shm);//删除共享内存头部
  92. shmctl(fifo->shmid, IPC_RMID, );//删除整个共享内存
  93.  
  94. //释放fifo的内存
  95. free(fifo);
  96. }

shmfifo_send.c

  1. #include "shmfifo.h"
  2. /*
  3. typedef struct stu
  4. {
  5. char name[32];
  6. int age;
  7. }STU;
  8. */
  9. int main(void)
  10. {
  11. shmfifo_t *fifo = shmfifo_init(,sizeof(STU),);
  12.  
  13. STU s;
  14. memset(&s, , sizeof(STU));
  15. s.name[] = 'A';
  16. int i;
  17. for(i=;i<;i++)
  18. {
  19. s.age = + i;
  20. shmfifo_put(fifo,&s);
  21. s.name[] = s.name[] + ;
  22. printf("send ok\n");
  23. }
  24. return ;
  25. }

shmfifo_recv.c

  1. #include "shmfifo.h"
  2. /*
  3. typedef struct stu
  4. {
  5. char name[32];
  6. int age;
  7. }STU;
  8. */
  9. int main(void)
  10. {
  11. shmfifo_t *fifo = shmfifo_init(,sizeof(STU),);
  12.  
  13. STU s;
  14. memset(&s, , sizeof(STU));
  15.  
  16. int i;
  17. for(i=;i<;i++)
  18. {
  19. shmfifo_get(fifo,&s);
  20. printf("name = %s, age = %d\n",s.name,s.age);
  21. }
  22. return ;
  23. }

shmfifo_free.c

  1. #include "shmfifo.h"
  2.  
  3. int main(void)
  4. {
  5. shmfifo_t *fifo = shmfifo_init(,sizeof(STU),);
  6. shmfifo_destroy(fifo);
  7. return ;
  8. }

Makefile

  1. .PHONY:clean all
  2. CC=gcc
  3. CFLAGS=-Wall -g
  4. BIN= shmfifo_send shmfifo_recv shmfifo_free
  5. OBJS1=shmfifo_send.o shmfifo.o ipc.o
  6. OBJS2=shmfifo_recv.o shmfifo.o ipc.o
  7. OBJS3=shmfifo_free.o shmfifo.o ipc.o
  8. all:$(BIN)
  9. %.o:%.c
  10. $(CC) $(CFLAGS) -c $< -o $@
  11. shmfifo_send:$(OBJS1)
  12. $(CC) $(CFLAGS) $^ -o $@
  13. shmfifo_recv:$(OBJS2)
  14. $(CC) $(CFLAGS) $^ -o $@
  15. shmfifo_free:$(OBJS3)
  16. $(CC) $(CFLAGS) $^ -o $@
  17.  
  18. clean:
  19. rm -f *.o $(BIN)

system v共享内存与信号量综合的更多相关文章

  1. 第三十三章 System V共享内存与信号量综合

    用信号量解决生产者.消费者问题 实现shmfifo ip.h #ifndef _IPC_H #define _IPC_H #include <unistd.h> #include < ...

  2. Linux进程通信之System V共享内存

    前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...

  3. 阐述linux IPC(五岁以下儿童):system V共享内存

    [版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途]         system V共享内存和posix ...

  4. php进程(线程)通信基础--System V共享内存

    PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项  System V消息,--enable-sysvmsg   System V信号量支持,--enable-sysvsem ...

  5. System V共享内存介绍

    (一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...

  6. System V共享内存

    目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...

  7. UNIX环境高级编程——System V 共享内存区

    共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...

  8. Linux IPC实践(9) --System V共享内存

    共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...

  9. System V 共享内存区

    1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...

随机推荐

  1. oracle中给表和列起别名

    SELECT xxmc,sname as xsxm,sex,phone,address jzdz FROM student s LEFT JOIN xxjbxx x ON x.sid = s.sid ...

  2. Eclipse直接打开类文件/文件夹所在的本地目录

    1.Eclipse原生的文件浏览操作 选择项目目录/文件 按 ALT+SHIFT +W , 会弹出菜单点击 System Explorer 就可以打开文件所在的本地目录了: 设置工具目录 Run -- ...

  3. python模块安装注意事项

    在安装python的第三方模块时,需要注意路径问题. 1.如果python是按默认位置安装的,则可以直接在命令提示符中进行安装,即pip install module_name. 2.如果python ...

  4. Intersecting Lines

    Intersecting Lines We all know that a pair of distinct points on a plane defines a line and that a p ...

  5. 水题系列二:PhoneNumbers

    问题描述: Phonenumbers 企业喜欢用容易被记住的电话号码.让电话号码容易被记住的一个办法是将它写成一 个容易记 住的 单词或 者短语 .例如 ,你 需要给 滑铁卢 大学打 电话时 ,可 以 ...

  6. 更改pip源至国内镜像

    更改pip源至国内镜像   经常在使用Python的时候需要安装各种模块,而pip是很强大的模块安装工具,但是由于国外官方pypi经常被墙,导致不可用,所以我们最好是将自己使用的pip源更换一下,这样 ...

  7. ASP.Net MVC(4) 之js css引用与压缩

    资源引用 可以用即可以直接使用“~”来表示根目录. 引入js <script src="~/Areas/OrderManage/JS/Form.js"></scr ...

  8. web技术栈中不可或缺的Linux技术

    Web技术最重要的载体便是服务器,服务器运行在公共的网络环境下,为广大的用户提供网页浏览.信息通讯.消息推送等服务,从最开始的硬件服务器到虚拟主机技术,再到虚拟化技术的出现和云概念的兴起,绝大部分都是 ...

  9. python 学习笔记 字符串和编码

    字符编码:因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理,最早的计算机在设计时采用8个比特(bit)作为一个字节 (byte),所以,一个字节能表示的最大的整数是255(二进 ...

  10. linux图形和命令界面切换

    一.系统不在虚拟机中的情况 使用ctrl+alt+F1~6切换到命令行界面:ctrl+alt+F7切换到图形界面 二.系统在虚拟机中的情况 Ctrl+Alt+shift+F1~6切换到命令行界面:使用 ...