在上一篇“OS: 生产者消费者问题(多进程+共享内存+信号量)”中提到的方法二: 如果进程之间并没有父子关系,但是协商好了共享存储的 KEY , 那么在每个进程中,就可以通过 KEY 以及 shmget 函数获得共享存储的 I D , 进而通过 shmat 函数获得共享存储的实际地址,最后访问。

本文采用此种方式进行同步生产者和消费者。

1、头文件myshm.h: 要用到的定义和说明

/*
* myshm.h
*
* Created on: Aug 3, 2013
* Author: root
*/ #ifndef MYSHM_H_
#define MYSHM_H_
#endif /* MYSHM_H_ */ #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#define SHMSZ 256 union semun{
int val;
struct semid_ds * buf;
unsigned short * array;
}; void init_a_semaphore(int sid, int semnum, int initval){
union semun semopts;
semopts.val = initval;
semctl(sid, semnum, SETVAL, semopts);
} int semaphore_P(int sem_id){
struct sembuf sb;
sb.sem_num=;
sb.sem_op = -;
sb.sem_flg = SEM_UNDO;
if(semop(sem_id, &sb, ) == -){
printf("semaphore_P failed.\n");
return ;
}
return ;
} int semaphore_V(int sem_id){
struct sembuf sb;
sb.sem_num=;
sb.sem_op = ;
sb.sem_flg=SEM_UNDO;
if(semop(sem_id, &sb, ) == -){
printf("semaphore_V failed.\n");
return ;
}
return ;
}

2、生产者程序productProcess.c:

#include "myshm.h"

int main(){
char * shm, *s;
int shmid;
int producer, consumer, i;
char readbuf[SHMSZ]; if((consumer = semget((key_t), , IPC_CREAT|)) == -){
printf("server consumer semget failed.\n");
exit();
}
init_a_semaphore(consumer, , ); if((producer = semget((key_t), , IPC_CREAT|)) == -){
printf("server producer semget failed.\n");
exit();
}
///printf("ftok(\"consumer\", 0) = %d", (key_t)1234);
//printf("ftok(\"consumer\", 0) = %d", (key_t)5678);
//printf("ftok(\"consumer\", 0) = %d", ftok("consumer", 0));
//printf("ftok(\"producer\", 0) = %d", ftok("producer", 0));
init_a_semaphore(producer, , ); if((shmid = shmget(ftok("shared",), SHMSZ, | IPC_CREAT)) == -){
printf("server shmget failed.\n");
exit();
}
if((shm = shmat(shmid, (unsigned char*), )) == -){
printf("server shmat failed.\n");
exit();
} for(i=;;i++){
printf("Enter text:");
fgets(readbuf, SHMSZ, stdin);
semaphore_P(producer);
printf("process %d enter pv key area", getpid());
sprintf(shm, "Message %4d from producer %d is \"%s\"\n",i, getpid(), readbuf);
semaphore_V(consumer);
if(strcmp(readbuf, "end") == ){
break;
}
}
return ;
}

3、消费者程序ConsumerProcess.c:

#include "myshm.h"

int main(){
char * shm;
int shmid;
int producer, consumer, i;
if((consumer = semget((key_t), , IPC_CREAT|)) == -){
printf("consumer semget failed.\n");
exit();
}
//init_a_semaphore(consumer, 0, 1);
if((producer = semget((key_t), , IPC_CREAT|)) == -){
printf("producer semget failed.\n");
exit();
}
//init_a_semaphore(producer, 0, 1); if((shmid = shmget(ftok("shared", ), SHMSZ, |IPC_CREAT)) == -){
printf("shmget failed\n");
exit();
}
if((shm = shmat(shmid, (unsigned char *), )) == -){
printf("shmat failed.\n");
exit();
} for(i=;;i++){
printf("Prepare to get Data from memory\n");
semaphore_P(consumer);
printf("enter pv key memory\n");
printf("Data received:%s\n", shm); sleep();
semaphore_V(producer);
if(strcmp(shm, "end") == ){
break;
}
} semctl(producer, , IPC_RMID,);
semctl(consumer, , IPC_RMID, ); return ;
}

OS: 生产者消费者问题(二) ---- 系统V IPC通信-信号量和共享内存的更多相关文章

  1. System V IPC 之信号量

    本文继<System V IPC 之共享内存>之后接着介绍 System V IPC 的信号量编程.在开始正式的内容前让我们先概要的了解一下 Linux 中信号量的分类. 信号量的分类 在 ...

  2. 进程间通信IPC:消息队列,信号量,共享内存

    2015.3.4星期三 阴天 进程间通信:IPC 文件对象:记录文件描述符,文件开关等 IPC标示符:系统全局的流水号两个进程要通信,打开的是唯一的对象进行通讯,通过key操作 XSI IPC:消息队 ...

  3. Linux进程IPC浅析[进程间通信SystemV共享内存]

    Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到 ...

  4. (转)OS: 生产者消费者问题(多进程+共享内存+信号量)

    转:http://blog.csdn.net/yaozhiyi/article/details/7561759 一. 引子 时隔一年再次用到 cout 的时候,哥潸然泪下,这是一种久别重逢的感动,虽然 ...

  5. [OS] 生产者-消费者问题(有限缓冲问题)

    ·最简单的情形--(一个生产者 + 一个消费者 + 一个大小为1的有限缓冲) 首先来分析其中的同步关系: ·必须在生产者放入一个产品之后,消费者才能够从缓冲中取出产品来消费.·只有在消费者从缓冲区中取 ...

  6. Linux系统编程之命名管道与共享内存

    在上一篇博客中,我们已经熟悉并使用了匿名管道,这篇博客我们将讲述进程间通信另外两种常见方式--命名管道与共享内存. 1.命名管道 管道是使用文件的方式,进行进程之间的通信.因此对于管道的操作,实际上还 ...

  7. Linux IPC实践(10) --Posix共享内存

    1. 创建/获取一个共享内存 #include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #inc ...

  8. System V IPC(2)-信号量

    一.概述                                                    System V信号量与System V消息队列不同.它不是用来在进程间传递数据.它主要 ...

  9. 4GB内存原32位系统(x86)取舍问题,显卡共享内存Win8.1完全不用担心

    情景:集成显卡 配置: 4G显示3.25GB 此时系统自动将用不到的系统完全共享给显卡(768MB而不是256): 看显卡适配器信息,完全共享给了显卡 解说:上图总可用图形内存 = 图2中备用 + 硬 ...

随机推荐

  1. kvm无人值守安装centos 7虚拟机

    centos 7安装好KVM之后还要安装虚拟机,通过VNC连接手动安装centos 7虚拟机太麻烦了,所以无人值守安装是做好的.简单记录下. 无人值守安装centos 7前提是要安装KVM,并且能手动 ...

  2. 数据库的显示、创建、使用 、用户授权管理及忘记root用户后重置密码

    1.显示数据库 show databases; 默认的数据库及大致功能: mysql -- 用户权限 相关数据 test --用于用户测试数据 information_schema -MySQL 本身 ...

  3. Angular 2 技能图谱skill-map

    # Angular 2 技能图谱 ## 模块 ### 自定义模块 - 根模块 - 特性模块 - 共享模块 - 核心模块 ### 内置模块 - ApplicationModule 模块 - Common ...

  4. visual studio code -- python

    录: 前提: 已安装python 在vsc中安装pthon模块 快速入门 打开控制台(ctrl+shift+P):Python: Select Interpreter,选择python解释器 或者在软 ...

  5. cs224d 作业 problem set2 (二) TensorFlow 实现命名实体识别

    神经网络在命名实体识别中的应用 所有的这些包括之前的两篇都可以通过tensorflow 模型的托管部署到 google cloud 上面,发布成restful接口,从而与任何的ERP,CRM系统集成. ...

  6. C++——模板

    1.参数类型 template <typename T> void f1(T&);//实参必须是左值 f1(i);//对 f1(ci);//对,T的类型是const int f1( ...

  7. 算法刷题笔记-stack-四则运算

    题目描述: 给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果.你需要给出所有可能的组合的结果.有效的运算符号包含 +, - 以及 * . 示例 1: 输入: &qu ...

  8. Java语言基础及java核心

    一.Java语言特点 1. 简单 2. 面向对象 3. 分布式 4. 健壮 5. 安全 6. 中性架构跨平台 7. 超强的可移植性 8. 高性能 9. 多线程 二.java的环境变量 JAVA_HOM ...

  9. 力扣算法——139WordBreak【M】

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  10. 使用JMail发送邮件

    使用JMail做最简单的文本邮件发送: 第一步.下载JMail和JAF 第二步.解压放到本地classpath中 第三步.使用: public class MailService{    privat ...