进程通信(二)—— 信号量&内存共享

内存共享是进程间常用的通信方式,可以实现两个完全独立的进程通信。

在访问共享内存时,同时需要信号量进行访问控制。

使用ipcs -m命令可以查看系统共享内存,ipce -m + key 可以删除指定的共享内存。

对共享内存操作时,使用信号量对共享内存进行保护,类似与线程中的互斥锁。都可以看做是通过PV操作实现临界资源保护。

P:对信号量标记位-1,获取信号量,如果标记位为0,表示有其他进程占用资源,无法获取。

V:对信号量标记位+1,释放信号量,将资源释放,给其他进程使用。

信号量和内存共享需要使用到的函数类似,下面是具体代码实现,函数参数不具体介绍。

  1 //shmwrite.cpp
  2 #include <sys/types.h>
  3 #include <sys/sem.h>
  4 #include <sys/shm.h>
  5 #include <string.h>
  6 #include <iostream>
  7
  8 using namespace std;
  9
 10 const int SEMTAG = 0x2456;
 11 const int SHMTAG = 0x3443;
 12 const int MAXBUFFLEN = 1024;
 13
 14 class SemOp
 15 {
 16 public:
 17     SemOp():m_iSemID(0){};
 18     void InitSem();
 19     void GetSem();
 20     void ReleaseSem();
 21     void DelSem();
 22 private:
 23     int m_iSemID;
 24 };
 25
 26 class ShmOp
 27 {
 28 public:
 29     ShmOp():m_iShmID(0){};
 30     void InitShm();
 31     void WriteShm();
 32     void ReadShm();
 33     void DelShm();
 34 private:
 35     int m_iShmID;
 36     void *m_memAddr;
 37 };
 38
 39 void SemOp::InitSem()
 40 {
 41     if ((m_iSemID = semget(SEMTAG, 1, 0600|IPC_CREAT)) <= 0)
 42         cout<<"get semID failure!"<<endl;
 43     semctl(m_iSemID, 0, SETVAL, 1);
 44 }
 45 void SemOp::GetSem()
 46 {
 47     struct sembuf sem_get;
 48     sem_get.sem_num = 0;
 49     sem_get.sem_op = -1;
 50     sem_get.sem_flg = SEM_UNDO;
 51     semop(m_iSemID,&sem_get,1);
 52 }
 53 void SemOp::ReleaseSem()
 54 {
 55     struct sembuf sem_release;
 56     sem_release.sem_num = 0;
 57     sem_release.sem_op = 1;
 58     sem_release.sem_flg = SEM_UNDO;
 59     semop(m_iSemID,&sem_release,1);
 60 }
 61 void SemOp::DelSem()
 62 {
 63     semctl(m_iSemID, 0, IPC_RMID);
 64 }
 65
 66 void ShmOp::InitShm()
 67 {
 68     if ((m_iShmID = shmget(SHMTAG, MAXBUFFLEN, 0600|IPC_CREAT)) <= 0)
 69         cout<<"get m_iShmID failure!"<<m_iShmID<<endl;
 70 }
 71 void ShmOp::WriteShm()
 72 {
 73     char buff[MAXBUFFLEN];
 74     cin>>buff;
 75     m_memAddr = reinterpret_cast<void *>(shmat( m_iShmID, NULL, 0 ));
 76     memcpy(m_memAddr,buff,sizeof(buff));
 77
 78 }
 79 void ShmOp::ReadShm()
 80 {
 81     char buff[MAXBUFFLEN];
 82     m_memAddr = reinterpret_cast<void *>(shmat( m_iShmID, NULL, 0 ));
 83     memcpy(buff,m_memAddr,sizeof(buff));
 84     cout<<buff;
 85 }
 86 void ShmOp::DelShm()
 87 {
 88     shmdt(m_memAddr);
 89 }
 90
 91 int main()
 92 {
 93     SemOp sem;
 94     ShmOp shm;
 95
 96     sem.InitSem();
 97     shm.InitShm();
 98
 99     sem.GetSem();
100     shm.WriteShm();
101     sem.ReleaseSem();
102
103     shm.DelShm();
104     sem.DelSem();
105     return 0;
106 }

读共享内存代码类似,只需要修改main函数,对共享内存执行读操作。

 1 int main()
 2 {
 3     SemOp sem;
 4     ShmOp shm;
 5
 6     sem.InitSem();
 7     shm.InitShm();
 8
 9     sem.GetSem();
10     shm.ReadShm();
11     sem.ReleaseSem();
12
13     shm.DelShm();
14     sem.DelSem();
15     return 0;
16 }

执行写操作后,可以使用ipcs命令查看系统共享内存情况。

执行代码结果:

时间: 04-30

进程通信(二)—— 信号量&内存共享的相关文章

进程通信(信号量)

信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的 通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识.信号 量在此过程中负责数据操作的互斥.同步等功能. 当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用.大于0,资源可以请求,等于0,无资源可用,进程会进入睡眠状态直至资源可用. 当进程不再使用一个信号量控制的共享资源时,信号量的值+1,对信号量的值进行的增减 操作均为原子操作,这是由于信号量主要的作用是维护资源的互斥

linux 进程通信之 信号量

信号量又名信号灯,与其他进程间通信方式大不相同,主要用途是用来保护临界资源.进程可以根据它判断是否能访问某些共享资源.除了用于访问控制外,还可以用于进程同步. 分类: 二值信号灯:信号灯的值只能取0或1,类似与互斥锁.但两者有不同:信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值:互斥锁更强调进程,占用资源的进程使用完资源后,必须有进程本身来解锁.(我们常说的PV操作) 计数信号灯:信号灯的值可以取任意非负数.(多用于生产者消费者模型) 不管哪种信号灯,当信号灯的值为0时,会

进程通信之信号量笔记

                   信号量通信模块 信号量作用:主要的作用就是保护临街资源,也就是说,如果来年各 个进程都需要用到某个资源,那么通过信号量,让进程A和进程B分别占有一定的信号量,每次信号量只能准许一个进程访问,信号量是有时间限制的,这样就可以使两个进程都有机会访问同一个资源. 分类:二值信号量 :信号灯的只能取0和1,类似互斥概念.当资源为可用的时候,信号灯可以自己对资源信号灯进行修改,变为可用.二互斥锁概 念强调的是进程,进程占用完资源后,必须由该进程来解锁, 计数信号灯:信

进程通信之信号量的操作

信号量的概述:信号量是用来解决进程之间的同步与互斥问题的一种进程之间通信机制,包括一个称为信号量的变量和在该信号量下等待资源的进程等待队列,以及对信号量进程的两个原子操作(PV操作).其中信号量对应于某一个资源,取一个非负的整形值.信号量值指的是当前可用的该资源的数量,若它等于0则意味着目前没有可用资源. PV原子操作的具体定义为: P操作:如果有可用的资源(信号量值>0),则占用一个资源(给信号量值减一,进入临界区代码),如果没有可用的资源(信号量值等于0),则被阻塞到,知道系统将资源分配给该

进程通信之内存共享篇

进程通信之_ 内存共享 概念:共享内存是被多个进程共享的一部分物理内存.共享内存是进程间的共享数最快的方法,一个进程向共享内存区域写入数据,共享这个内存区域的所有进程就可以写入数据,所有进程就可以立刻看到其中的内容. 实现步骤;1.创建共享内存,使用shmget函数2.映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数 创建:int shmget (key_t key,int size,int shmflg)key 标识内存功效的键值0/ipc_private.成功返回

linux 进程通信之 共享内存

共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容. 关于共享内存使用的API key_t ftok(const char *pathname, int proj_id); #在IPC中,我们经常用一个 key_t 的值来创建或者打开 信号量,共享内存和消息队列.这个 key_t 就是由ftok函数产生的. pathname:指定的文件名,该文件必须是存在而且可以访问 proj_

Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存

Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:<linux编程从入门到精通>,<Linux C程序设计大全>,<unix环境高级编程> 参考:C和指针学习 说明:本文非常的长,也是为了便于查找和比较,所以放在一起了 Linux 传统的进程间通信有很多,如各类管道.消息队列.内存共享.信号量等等.但它们都无法介于内核态与用户态使用,原因如表 通信方法 无法介于内核态与用户态的原因 管道(不包括命名管道) 局限于父子进程间的通信. 消息队列 在

进程通信之共享内存

共享内存 共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自

Linux程序设计学习笔记----System V进程通信(共享内存)

转载请注明出处:http://blog.csdn.net/suool/article/details/38515863 共享内存可以被描述成内存一个区域(段)的映射,这个区域可以被更多的进程所共享.这是IPC机制中最快的一种形式,因为它不需要中间环节,而是把信息直接从一个内存段映射到调用进程的地址空间. 一个段可以直接由一个进程创建,随后,可以有任意多的进程对其读和写.但是,一旦内存被共享之后,对共享内存的访问同步需要由其他 IPC 机制,例如信号量来实现.象所有的System V IPC 对象