进程通讯(五)--共享内存

18 篇文章 0 订阅
17 篇文章 0 订阅
 共享内存就是俩进程共同拥有的内存,一般执行一个程序,会给内存上分配该进程的空间吧。
  如果两个进程有一部分是使用共享内存,那么这俩进程其他部分会各自分配自己的内存空间,而使用共享内存的地方只会分配一个共有的内存空间,也就是说这部分共享内存空间都属于这两个进程,这部分空间对于这俩进程来说都是自己的。

共享内存本身不难理解,使用起来也无非是介绍几种函数,熟悉下用法。和其他IPC比较一下,还是很容易的。
但是关键的是共享内存一个主要的问题是解决同步问题,即这片内存是共享的,就会存在很频繁的数据竞争问题,而共享内存函数本身也没有提供同步的功能。因此往往需要我们把信号量引入进来,和共享内存一起使用才能解决问题。   当然虽然共享内存同步异步这里稍微麻烦,但是换来的确实很大很大的通讯量,比起消息队列管道那些小水管的数据传送,共享内存相当于在内存上直接共享数据 ,也是这几种IPC中最大的。

这之前还是先介绍下函数吧。
其实比起之前消息队列信号量这几种IPC来讲,都是大同小异。
有着类似的shmget shmctl。但是有俩函数稍微不同,就是shmat 和shmdt,这俩函数前者负责将创建的共享内存空间链接到使用函数的进程中,一个负责断开共享内存空间和使用该函数的进程空间。

四个函数具体声明如下

1.int shmget(key_t key,size_t size,int shmflg);
第一个key值自己随意定义
第二个参数size是自己要开辟的共享内存大小
第三个参数就是权限标志 类似 0664|IPC_CREAT 这样的
失败返回-1 成功返回标识符shmid

2.void *shmat(int shmid,const void * shm_addr,int shmflg);
第一个参数就是shmget返回的标识符
第二个参数为共享内存连接到当前进程中的地址,可以自己给定,一般都是NULL让系统自己选择最适合的。
第三个参数就是宏,可以SHM_RDONLY表示只读。也可以写0表示默认的可读可写。
失败返回-1  成功返回指向共享内存第一个字节的指针

3.int shmdt(void *shmatrt)
参数为 shmat中返回的指针。
失败返回-1,成功为0。


4.int shmctl(int shm_id,int command,struct shmid_ds*buf);
和消息队列与信号量的控制函数几乎一样。
一般我们用它删除共享内存的比较多,第二个参数取IPC_RMID 第三个参数为0就好。其他用法可以参考前两篇博客里的控制函数。

照样拿一道题举例,一个进程负责读取用户输入的单词写入共享内存,另一个进程负责统计个数并打印出来
这里就要引用信号量了。
我们知道当一个进程正在读取用户输入的单词并写入内存时,另一个统计单词个数的进程是不能工作的,因为第一个进程可能还没写入完毕,此时读取统计个数可能会发生错误。
当第一个进程写入用户输入的单词完毕后,第二个进程开始统计个数。此时第一个进程就不能继续读取用户输入的单词并写入了,如果写入的话,第二个进程统计个数时就可能发生错误,正统计的单词时被写入的新单词覆盖了。
因此我们要求这俩进程要同步运行。即第一个进程输入写入时,统计单词个数的进程要等待,写入完毕后,统计单词的进程开始工作,输入写入的进程要等待,并且这俩必须一个来一次,交换着等待。
所以我们要引入两个信号量。  比如甲 乙信号量,甲信号量初值为1,乙信号量初值为0。
我们把负责读取用户输入的单词这个进程简称为A.
把统计个数并打印的进程简称为B.
我们的目的是让A先运行,B等着,然后A完成功能后,B运行,A等着。然后B完成功能后,A运行,B等着.....这样一直你来我往的等待。
所以我们可以让A先对甲信号量p操作,B对乙信号量p操作,由于乙初值为0,所以B不能运行。只能A运行。
A运行达到条件后对乙信号量V操作,此时B就可以运行了,然而A由于一开始已经p操作一次了,所以再次循环到输入时,会卡在对甲信号量的p操作。  此时B运行完了,然后B再对甲信号量v操作,这时A又可以运行了,B再循环时又卡在对乙的p操作了。这样就完成了同步的控制。

代码:
读取用户输入的进程




统计单词个数的进程:




运行结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值