📄 在linux中实现内部进程通信 - 开发者 - zdnet china.htm
字号:
开发</A> <FONT color=#6284b1>|</FONT> <A class=white
href="http://www.zdnet.com.cn/developer/category/Webdevelop">Web
开发</A> <FONT color=#6284b1>|</FONT> <A class=white
href="http://www.zdnet.com.cn/developer/category/Linux">Unix/Linux</A>
<FONT color=#6284b1>|</FONT> <A class=white
href="http://www.zdnet.com.cn/developer/category/devprocess">开发过程</A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><!-- End nav_small-->
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width=750>
<TBODY>
<TR>
<TD bgColor=#83a3cb width=1><IMG height=500
src="F:\项目文档\进程间通信\在Linux中实现内部进程通信 - 开发者 - ZDNet China.files\margin(1).gif"
width=1></TD>
<TD bgColor=#1e5c99 width=9><IMG height=1
src="F:\项目文档\进程间通信\在Linux中实现内部进程通信 - 开发者 - ZDNet China.files\margin(1).gif"
width=9></TD>
<TD bgColor=#ffffff width=1><IMG height=500
src="F:\项目文档\进程间通信\在Linux中实现内部进程通信 - 开发者 - ZDNet China.files\margin(1).gif"
width=1></TD>
<TD align=middle bgColor=#ffffff vAlign=top width=728><BR>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD vAlign=top width=558>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=558>
<TBODY>
<TR>
<TD vAlign=top>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=558>
<TBODY>
<TR>
<TD colSpan=3 height=10><IMG height=10
src="F:\项目文档\进程间通信\在Linux中实现内部进程通信 - 开发者 - ZDNet China.files\margin(1).gif"
width=1></TD></TR>
<TR>
<TD width=10><IMG height=1
src="F:\项目文档\进程间通信\在Linux中实现内部进程通信 - 开发者 - ZDNet China.files\margin(1).gif"
width=10></TD>
<TD vAlign=top><!--start story --><!-- BEGIN:CHANNEL HEADER --><!-- END:CHANNEL HEADER -->
<P><BR><B><SPAN class=h2>在Linux中实现内部进程通信</B></SPAN>
<BR><BR><SPAN class=hui>作者: <A
href="mailto:developer@zdnet.com.cn"><FONT
color=blue>ZDNet China</FONT></A></SPAN><BR><SPAN
class=hui>Wednesday, November 26 2003 2:33 PM</SPAN> <!-- BEGIN:STORY -->
<TABLE>
<TBODY>
<TR>
<TD class=text1>
<P><IMG align=left alt=本文译自Builder.com,未经许可请勿转载
height=32
src="在Linux中实现内部进程通信 - 开发者 - ZDNet China.files/builder.jpg"
width=168>
<P>Linux给我们提供了丰富的内部进程通信机制,包括共享内存、内存映射文件、先入先出(FIFO)、接口(sockets)以及多种用于同步的标识。在本文中,我们主要讨论一下共享内存和内存映射文件技术。</P>
<TABLE align=right border=0 cellPadding=0
cellSpacing=0 width=0>
<TBODY>
<TR>
<TD align=middle><IMG
src="在Linux中实现内部进程通信 - 开发者 - ZDNet China.files/advertisement_e1.gif"></TD></TR>
<TR>
<TD><!--start banner ad--><!--ba-->
<SCRIPT language=JavaScript1.1
src="在Linux中实现内部进程通信 - 开发者 - ZDNet China.files/code;sz=1x1;ord=1107613023"> </SCRIPT>
<NOSCRIPT><A
href="http://ad.cn.doubleclick.net/jump/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=1107613023?"><IMG
border=0
src="在Linux中实现内部进程通信 - 开发者 - ZDNet China.files/817-grey.gif"></A>
</NOSCRIPT><!--end banner ad--></TD></TR></TBODY></TABLE>
<P>一般来说,内部进程通信(interprocess
communication)也就是IPC,是指两个或两个以上进程以及两个或者两个以上线程之间进行通信联系。每个IPC机制都有不同的强项或者弱点,不过没有一个IPC机制包含内建的同步方法。因此程序员不但需要自己在程序中实现同步,而且还需要为了利用IPC机制而自己开发通信协议。</P>
<P>
<H5>共享内存</H5>
<P>使用共享内存和使用<I>malloc</I>来分配内存区域很相似。使用共享内存的方法是:</P>
<P>1.
对一个进程/线程使用shmget分配内存区域。</P>
<P>2.
使用shmat放置一个或多个进程/线程在共享内存中,你也可以用shmctl来获取信息或者控制共享区域。</P>
<P>3.
使用shmdt从共享区域中分离。</P>
<P>4.
使用shmctl解除分配空间</P>
<P>下面是个例子: </P>
<P><FONT color=#006600>//建立共享内存区域</FONT><FONT
color=#0066ff><BR>intshared_id;<BR>char
*region;<BR>const intshm_size =
1024;<BR><BR>shared_id = shmget(IPC_PRIVATE,<FONT
color=#006600>//保证使用唯一ID</FONT><BR> shm_size,<BR> IPC_CREAT
| IPC_EXCL |<FONT
color=#006600>//创建一个新的内存区域</FONT> <BR> S_IRUSR
| S_IWUSR);<FONT
color=#006600>//使当前用户可以读写这个区域</FONT><BR><BR><FONT
color=#006600>//交叉进程或生成进程.</FONT><BR><BR> <FONT
color=#006600><BR>//将新建的内存区域放入进程/线程</FONT><BR>region
= (char*) shmat(segment_id, 0, 0);<BR><BR><FONT
color=#006600>//其他程序代码</FONT><BR>...<BR><BR><FONT
color=#006600>//将各个进程/线程分离出来</FONT><BR>shmdt(region);<BR><BR><FONT
color=#006600>//破坏掉共享内存区域</FONT><BR>shmctl(shared_id,
IPC_RMID, 0); </FONT></P>
<P>共享内存是Linux中最快速的IPC方法。他也是一个双向过程,共享区域内的任何进程都可以读写内存。这个机制的不利方面是其同步和协议都不受程序员控制,你必须确保将句柄传递给了子进程和线程。</P>
<P>
<H5>内存映射文件</H5>
<P>内存映射文件不仅仅用于IPC,在其他进程中它也有很大作用。如果你需要将一个分配的缓冲区初始化为零,只要记住<I>/dev/zero
</I>。你也可以通过将文件映射到内存中以提高其性能。它使你可以像读写字符串一样读写文件。下面是个例子:</P>
<P><FONT color=#0066ff>const char filename[] =
"testfile";<BR>intfd;<BR>char
*mapped_mem;<BR>const intflength = 1024;<BR>fd =
open(filename, O_RDWR | O_CREAT, S_IRUSR |
S_IWUSR);<BR>lseek(fd, flength + 1,
SEEK_SET);<BR>write(fd, "\0", 1);<BR>lseek(fd, 0,
SEEK_SET);<BR><BR>mapped_mem =
mmap(0,<BR> flength,<BR> PROT_WRITE,<FONT
color=#006600>
//允许写入</FONT><BR> MAP_SHARED,<FONT
color=#006600>//写入内容被立即写入到文件</FONT><BR> fd,<BR> 0);<BR><BR>close(fd);<BR><BR><FONT
color=#006600>//使用映射区域.</FONT><BR>...<BR><BR>munmap(file_memory,
flength); </FONT></P>
<P>利用内存映射来处理IPC的好处是在整个过程中你不需要处理句柄:只要打开文件并把它映射在合适的位置就行了。你可以在两个不相关的进程间使用内存映射文件。</P>
<P>使用内存映射的缺点是速度不如共享内存快。如果凑巧文件很大,所需要的虚拟内存就会很大,这样会造成整体性能下降。</P><IMG
align=left height=140 src="" width=90>
<HR>
<P>文本作者Mike Owens是一名Allscripts
Healthcare解决方案的软件工程师,他从事软件行业已逾八年。</P>
<HR>
<BR><BR>责任编辑:<A
href="mailto:li_ning@zdnet.com.cn?subject=http://www.zdnet.com.cn/developer/code/story/0,2000081534,39036118,00.htm">李宁</A><BR><FONT
color=#ff0000><BR>欢迎<A
href="http://forums.zdnet.com.cn/cgi-bin/leoboard.cgi"
target=new>评论</A>或<A
href="mailto:li_ning@zdnet.com.cn?subject=投稿:(稿件题目)">投稿</A>
</FONT>
<P></P></TD></TR></TBODY></TABLE><!-- END:STORY --><!-- BEGIN:PREVIOUS/NEXT --><BR
clear=all>
<DIV align=right><A
href="http://www.zdnet.com.cn/developer"><FONT
face="Arial, Helvetica" size=-1>【返回技术首页
】</FONT></A> </DIV><!-- END:PREVIOUS/NEXT --><!-- BEGIN:TALKBACK --><SPAN
class=h2><FONT color=#880000>本文为ZDNet
China版权所有,未经许可严禁转载。</FONT></SPAN> <BR><BR><FONT
face=tahoma size=-1><A
href="http://www.zdnet.com.cn/developer/code/story/talkback.htm?AT=39183560-2000081534t-20000560c"><IMG
border=0
src="在Linux中实现内部进程通信 - 开发者 - ZDNet China.files/maincolumn_header_talkback.gif">
</A>
<P></FONT><!--end talkback --><!-- BEGIN:PAGE FUNCTIONS -->
<HR color=#444444 SIZE=1>
<TABLE border=0 borderColorDark=#cccccc
borderColorLight=#ffffff cellPadding=2 cellSpacing=0
width="100%">
<TBODY>
<TR>
<TD align=middle noWrap><SPAN class=gslink12><FONT
style="FONT-SIZE: 9pt">| <A class=gslink12
href="http://www.zdnet.com.cn/common/emailfriend/emailfriend.htm?AT=39183560-2000081534t-20000560c">推荐朋友</A>
| <A class=gslink12
href="http://www.zdnet.com.cn/common/printfriendly/printfriendly.htm?AT=39183560-2000081534t-20000560c">打印本文</A>
|</FONT></SPAN> </TD></TR></TBODY></TABLE><!-- END:PAGE FUNCTIONS --><!-- BEGIN:RELATED LINKS -->
<UL></UL></SPAN><!-- END:RELATED LINKS --><!-- BEGIN:TALKBACK --><!-- END:TALKBACK --><!--end story --></TD>
<TD width=10><IMG height=1
src="F:\项目文档\进程间通信\在Linux中实现内部进程通信 - 开发者 - ZDNet China.files\margin(1).gif"
width=10></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD>
<TD vAlign=top width=160><!--start rightnav -->
<TABLE border=0 cellPadding=0 cellSpacing=0 width=160>
<TBODY>
<TR>
<TD><!--hand--><!--hand --><!--start date -->
<TABLE border=0 cellPadding=2 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD align=right><!--date--><SPAN class=Text2>2004 年 8月
19日</SPAN> <SPAN class=Text2> </SPAN> <!--end date--></TD></TR></TBODY></TABLE><!--end date --><!--start search -->
<SCRIPT language=javascript>
<!--
function form_submit1()
{
if (form_submit())
{
form1.submit ();
}
return false;
}
function form_submit()
{
var n,thestr,alert_str,re;
//要屏蔽的字符
alert_str="#[]{}&, "
thestr=document.form1.searchstring.value;
if (thestr=="")
{
alert("输入内容不能为空!")
return false;
}
str_len=thestr.length ;
// alert("str_len="+str_len);
//去除头尾
thestr_head=thestr;
thestr_head_noalert=thestr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -