荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: playboy (冷冷的太阳), 信区: Program
标  题:  Win32 行程通讯的观念与技术(3)
发信站: BBS 荔园晨风站 (Mon Mar 20 15:47:06 2000), 转信

关於执行效能的讨论
    许多人耽心IPC的执行效能,的确,先不说别的,光是启动另一个Process本身就
比启动一个Thread 的Overhead要高上很多。如果涉及协调的问题,建立一个Mutex的
时间也比Critical section慢上不知多少倍。遗憾的是我们却也别无选择,因为
Critical section在Multi-Thread中固然简单好用,但是不能用在跨越行程边界的场合。
    但是要说 IPC 一定使得系统效能降低,未免也太过悲观了;平视与俯看的视野
是不同的。这年头大家都将Client/Server挂在嘴边,充分运用合理分配整个公司的
运算资源才能提高整体的效能,我想 IPC 在这 自有其应用的价值与效益。
    另外一个导致IPC执行效率不彰的元凶来自不良的设计,着名的例子是所谓的
Busy-loop 一个什麽也不做只有一行程式不断地期待的回圈。以稍早的老板与会计
小姐为例,如果老板交办事情之後却将全部的事都停下来,来回踱步只为专心等着
会计小姐回来,时间没有花在刀口上的结果当然效率不彰。找出效率的瓶颈设法调
校是件长期奋战的工作,如同管理是持续不断的合理化。
    此处还有一个迷思也有待澄清,同步与非同步对於执行效能的影响是视情况而
定的,并不能说非同步一定会比同步快,抽样样本很小或资料量偏小时,同步往往
比非同步快。比较公允的说法应该是:同时有好几件工作要处理时,整体来说「非
同步」往往快一些。以刚才的提款的事情为例,老板亲自去提款未必比小姐慢,但
是如果老板同时有好几件工作要处理时,非同步的好处就很明显了。

Win32支援的IPC相关技术
    上述的讨论与其说是针对TwinApp的观察,不如说是发扬光大了,然而观念上早已不纯
粹界定在档案系统的实体档案。的确,
资料位於何处的份际如今是越来越模糊了,虚拟的记忆体实际上是档案,虚拟的档案
结果是记忆体。
    Win32 API 中有一个好玩的东西叫做File-mapping;基本的观念是开启一个档案
并将之对映到某一块记忆体,有趣的是,虽然程式是针对这块记忆体操作,实际上改
变的却是档案。
更好玩的是你不必真的在硬碟 开一个实体档案,而是使用分页置换档(paging file)
的一块空间权充当作档案。这个虚拟的档案空间(或者你要说是记忆体)可以为行程间
共享,通常我们管它一个特别的名字叫 Share-memory,共享记忆体。
    由於它的确不是真正的档案,行程间不仅省去特定磁碟目录档案等约定,也毋须
在意谁是最後走的要负责删除档案,当然啦,即使当机不会留下一些垃圾档案。彼此
分享的是正好是同一块记忆体,资料一旦写入,这项改变也立即反应到别的行程。

使用ShareMemory的大致步骤如下所述

呼叫CreateFileMapping() API函数建立File-mapping核心物件.
    CreateFileMapping()函数的第一个引数原本应该是CreateFile()开档所得的档案
物件Handle,若是传入$FFFFFFFF则是以分页置换档(paging file)的一部划作共享记
忆体。函数的最後一个引数是这块区域的叁考名称,行程间彼此将根据此一相同的识
别名称叁考同一块共享记忆体。

FHandle := CreateFileMapping(
    $FFFFFFFF, // Shared memory File,Handle 传入 $FFFFFFFF
    nil, // 不设安全属性
    PAGE_READWRITE, // 存取模式设定为可读写以便行程交换资料ㄖ房占洌谡酱嫒≌
饪楣蚕砑且涮逯埃颐堑媒淙?
或部分映射回行程本身的位址空间中。呼叫MapViewOfFile()的用意即是在此,该函数
将传回mapped view 「视野」的起头(就是指标啦),接下来的就是用这个指标存取记
忆体了。
FFileView := MapViewOfFile(
    Fhandle, // File-mapping object 的 Handle 值
    FILE_MAP_ALL_ACCESS, // 设为 FILE_MAP_ALL_ACCESS 开放存取
    0, // 模式以便顺利存取共享记忆体
    0,
    Size); // 预备映射回来的 byte 数

最後,别忘了使用UnmapViewOfFile()归还指标并呼叫CloseHandle()释放
File-mapping核心物件。
    碍於篇辐,完整的程式码请读者叁阅ShareMem目录的 DemoSMem专案。
另外,为了方便使用,这些CreateFileMapping(),MapViewOfFile()等函数
已经包装进TSharedMem这个类别。

Mutex
    Shared memory的示范专案DemoSMem留下诸多悬疑待解,或许你也正有
相同的疑问:既然两个行程都利用这块记忆体,那我们怎麽知道什麽时候
资料改变了?此外,如何防止行程同时读写资料?
    的确,行程通讯既是两个以上的个体,协调是必然存在的负担,要避
免两个行程同时使用关键资源,Mutex(互斥器)的使用是你必备的技术。
    从字面上解释,互斥意思是同一时间唯一;换句话说,同一时间最多
只许握有Mutex的执行绪(Thread)有权使用关键资源,其他的执行绪若要使
用只有等待。嗯! 在Mutex与Event这两节我将暂时改口为执行绪,事实上
这才是真正的CPU排程单位,由於每个行程至少有个Thread(主执行绪),这
样的称呼应该是与本文行程通讯的主旨不相违背的。

--
※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.90]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店