知识讲解Unix操作系统共享内存
发布时间:2022-10-29 11:24:37 所属栏目:Unix 来源:
导读: Unix操作系统中,共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据
|
Unix操作系统中,共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于Unix操作系统像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域unix主机空间,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。 因此,Unix操作系统采用共享内存的通信方式效率是非常高的。 共享内存(sharedmemory)是Unix操作系统下的多进程之间的通信方法,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。本文介绍如何在Client/Server方式下实现多个程序间共享内存。 Unix操作系统问题分析 多个程序之间共享内存,首先要解决的问题是怎样让各个程序能够访问同一块内存和相同的信号量。共享内存的id可以通过调用shmget(key_tkey,size_tsize,intshmflg)函数取得;信号量的id可以通过调用semget(key_tkey,intnsems,intsemflg)函数取得。实际上,只要在调用这两个函数时使用相同的key值,各程序之间就能达到共享内存的目的。 Unix操作系统通过调用key_tftok(constchar*path,intid)函数来产生key值,如果各程序都用同样的参数来调用此函数,自然也就得到相同的key值了。例子中各个程序都使用key=ftok("/",0)得到相同的key值,再进而由key值得到相同的共享内存id和信号量id。 第二个要解决的问题是如何控制多个程序并发访问共享内存。本文的例子模拟在Client/Server方式下,由一个Server产生数据,多个Client去读取数据的操作。常规的方法是设一个信号量,Unix操作系统将访问共享内存的程序作为临界区来处理。程序进入时用p()操作取得锁,退出时用v()操作释放锁。但这样做有两个问题:一是这样各个程序就处于平等的地位,而实际中往往Server的优先级应该比Client更高。 比如,在股票行情应用程序中,共享内存里存放行情信息,Server负责定时更新;Client是CGI程序,负责按客户要求读取共享内存中的数据,然后再反馈给客户。在这种情况下,Server就不能等所有Client进程都读完了才开始写,因为这样Client取得的数据反而是过时的。二是各个Client之间由于都是读操作,所以没有必要互斥。 本文对这两个问题的解决方案是:只有Server进行p()、v()操作,信号量初始值设为0,p()操作将它加一,v()操作将它减一;Client读共享内存之前要先等待信号量的值为0,这样Server的p()操作总是成功,而Server的p()操作后,尚未进入临界区的Client只能等到Server执行v()操作后才能读。这样Server比Client优先,Client之间不互斥。但这样又产生另一个问题:一个Server开始写时,部分Client可能已经进入临界区,有可能出现读不完整的问题。 因此,Unix操作系统例子基于这样一个前提:Client程序比较简单,不会被阻塞,并且能够在一个时间片内执行完读取操作。本例中处于临界区中的Client数目是有限的,如果Server等待一个时间片(例子中是等待一分钟)后,Client就能全部退出临界区,这个问题就能排除。很多CGI程序能够满足这个假设条件,如果Client确实不满足条件,可以生成访 (编辑:我爱资讯网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
