⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chinaunix_net - unix进程之间的通信.htm

📁 描述unix,linux下进程间通信方式
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0041)http://www.chinaunix.net/jh/7/240959.html -->
<!-- Generated by LibHtt 2004-1-15 10:13:15   Templet source: /data0/chinaunix.net/cgisrc/do_html/viewtopics_jh.html  Warnings and errors: 0--><HTML><HEAD><TITLE>ChinaUnix.net - UNIX进程之间的通信</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META 
content=Linux,Freebsd,Solaris,Sco,HP-UX,IBM-AIX,cisco,oracle,java,cgi,mysql,perl,Apache,proFTP,Sendmail,Qmail,DNS,Squid,Rsync,SSL 
name=keywords>
<META content=中国UNIX技术社区 name=description>
<STYLE type=text/css>BODY {
	FONT: 12pt 宋体
}
TH {
	FONT: 12pt 宋体
}
INPUT {
	FONT: 12pt 宋体
}
SELECT {
	FONT: 12pt 宋体
}
TEXTAREA {
	FONT: 12pt 宋体
}
SELECT {
	FONT: 12pt 宋体
}
checkbox {
	FONT: 12pt 宋体
}
BODY {
	FONT-FAMILY: "宋体", "serif"; FONT-SIZE: 12pt
}
TD {
	FONT-FAMILY: "宋体", "serif"; FONT-SIZE: 12pt
}
P {
	FONT-SIZE: 9pt; LINE-HEIGHT: 150%
}
</STYLE>

<META content="MSHTML 5.00.3700.6699" name=GENERATOR></HEAD>
<BODY>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="75%">
  <TBODY>
  <TR>
    <TD height=45>
      <P align=center><A href="http://www.chinaunix.net/"><IMG alt=ChinaUnix.net 
      border=0 
      src="ChinaUnix_net - UNIX进程之间的通信.files/logo.gif"></A>&nbsp;&nbsp;<B>CU-SCO 
      UNIX讨论区精华帖 &nbsp;&nbsp;</B></P></TD></TR>
  <TR>
  <TR>
    <TD align=left height=40 vAlign=bottom><SMALL><A 
      href="http://www.chinaunix.net/">ChinaUnix.net</A> &gt; <A 
      href="http://www.chinaunix.net/forum">论坛首页</A> &gt; <A 
      href="http://www.chinaunix.net/jh">精华首页</A> &gt; <A 
      href="http://www.chinaunix.net/jh/7">SCO UNIX精华区</A> &gt; 正文 
</SMALL></TD></TR>
  <TR>
    <TD bgColor=#49ade9 colSpan=5 height=2 width="100%"><IMG height=1 
      src="ChinaUnix_net - UNIX进程之间的通信.files/bline.gif" 
width=1></TD></TR></TBODY></TABLE>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="75%">
  <TBODY>
  <TR>
    <TD align=middle bgColor=#edf0f5 height=40 vAlign=center><FONT 
      size=5><B>UNIX进程之间的通信</B></FONT></TD></TR>
  <TR>
    <TD align=middle bgColor=#edf0f5 height=20><SMALL>http://www.chinaunix.net 
      作者:<A 
      href="http://bbs.chinaunix.net/forum/profile.php?mode=viewprofile&amp;u=17234" 
      target=_blank>xzh2002</A>&nbsp;&nbsp;发表于:2004-01-10 
    15:00:32</FONT></SMALL></TD></TR>
  <TR>
    <TD align=middle bgColor=#edf0f5>
      <TABLE align=center border=0 cellPadding=0 cellSpacing=0 
      style="BORDER-COLLAPSE: collapse; WORD-BREAK: break-all" width="90%">
        <TBODY>
        <TR>
          <TD vAlign=top><BR>UNIX进程之间的通信 
            <BR><BR>  进程通讯是unix中很重要的知识。产生一个新的进程主要有以下3种方法: <BR><BR>1,fork调用; 
            <BR><BR>2,System调用; <BR><BR>3,Exec调用; 
            <BR><BR>  我们常说的进程通讯编程主要有以下3种方法: <BR><BR>1,Message&nbsp;queue队列编程; 
            <BR><BR>2,Tcp/IP&nbsp;socket编程; <BR><BR>3,共享内存编程; <BR><BR>一、进程调用 
            <BR><BR>1,产生进程Fork调用例子: <BR><BR>fork() <BR><BR>功能:创建一个新的进程. 
            <BR>语法:#include&nbsp;&lt;unistd.h&gt; 
            <BR>#include&nbsp;&lt;sys/types.h&gt; <BR>pid_t&nbsp;fork(); 
            <BR>说明:本系统调用产生一个新的进程,&nbsp;叫子进程,&nbsp;是调用进程的一个复制品.&nbsp;调用进程叫父进程,&nbsp;子进程继承了父进程的几乎所有的属性: 
            <BR>.&nbsp;实际UID,GID和有效UID,GID. <BR>.&nbsp;环境变量. <BR>.&nbsp;附加GID. 
            <BR>.&nbsp;调用exec()时的关闭标志. <BR>.&nbsp;UID设置模式比特位. 
            <BR>.&nbsp;GID设置模式比特位. <BR>.&nbsp;进程组号. <BR>.&nbsp;会话ID. 
            <BR>.&nbsp;控制终端. <BR>.&nbsp;当前工作目录. <BR>.&nbsp;根目录. 
            <BR>.&nbsp;文件创建掩码UMASK. <BR>.&nbsp;文件长度限制ULIMIT. 
            <BR>.&nbsp;预定值,&nbsp;如优先级和任何其他的进程预定参数,&nbsp;根据种类不同决定是否可以继承. 
            <BR>.&nbsp;还有一些其它属性. <BR><BR><BR>但子进程也有与父进程不同的属性: 
            <BR>.&nbsp;进程号,&nbsp;子进程号不同与任何一个活动的进程组号. <BR>.&nbsp;父进程号. 
            <BR>.&nbsp;子进程继承父进程的文件描述符或流时,&nbsp;具有自己的一个拷贝并且与父进程和其它子进程共享该资源. 
            <BR>.&nbsp;子进程的用户时间和系统时间被初始化为0. <BR>.&nbsp;子进程的超时时钟设置为0. 
            <BR>.&nbsp;子进程的信号处理函数指针组置为空. <BR>.&nbsp;子进程不继承父进程的记录锁. 
            <BR>返回值:&nbsp;调用成功则对子进程返回0,&nbsp;对父进程返回子进程号,&nbsp;这也是最方便的区分父子进程的方法.&nbsp;若调用失败则返回-1给父进程,子进程不生成. 
            <BR><BR>2,产生进程system调用例子: <BR><BR>功能:产生一个新的进程,&nbsp;子进程执行指定的命令. 
            <BR>语法:#include&nbsp;&lt;stdio.h&gt; 
            <BR>#include&nbsp;&lt;stdlib.h&gt; <BR>int&nbsp;system(string) 
            <BR>char&nbsp;*string; 
            <BR>说明:本调用将参数string传递给一个命令解释器(一般为sh)执行,&nbsp;即string被解释为一条命令,&nbsp;由sh执行该命令.若参数string为一个空指针则为检查命令解释器是否存在.该命令可以同命令行命令相同形式,&nbsp;但由于命令做为一个参数放在系统调用中,&nbsp;应注意编译时对特殊意义字符的处理.&nbsp;命令的查找是按PATH环境变量的定义的.&nbsp;命令所生成的后果一般不会对父进程造成影响.返回值:当参数为空指针时,&nbsp;只有当命令解释器有效时返回值为非零.若参数不为空指针,&nbsp;返回值为该命令的返回状态(同waitpid())的返回值.&nbsp;命令无效或语法错误则返回非零值,所执行的命令被终止.&nbsp;其他情况则返回-1. 
            <BR><BR><BR>[code:1:d22bc4f5e9]例子1:char&nbsp;command[81]; 
            <BR>int&nbsp;i; <BR>for&nbsp;(i=1;i&lt;8;i++)&nbsp;{ 
            <BR>sprintf(command,"ps&nbsp;-t&nbsp;tty%02i",i); 
            <BR>system(command); <BR>} <BR><BR><BR>例子2: 
            <BR><BR>char&nbsp;befehl[200];&nbsp;&nbsp;/*&nbsp;string&nbsp;buffer&nbsp;for&nbsp;csh&nbsp;command&nbsp;*/&nbsp; 
            <BR>char&nbsp;*runserver&nbsp;=&nbsp;"hosts1";&nbsp;/*&nbsp;server&nbsp;name&nbsp;*/ 
            <BR>short&nbsp;shift_act_l;&nbsp;/*&nbsp;currect&nbsp;shift&nbsp;number&nbsp;*/ 
            <BR>char&nbsp;shift_act_c[1]; 
            <BR>char&nbsp;shift_beg[20];&nbsp;/*&nbsp;shift&nbsp;begin&nbsp;*/ 
            <BR>char&nbsp;shift_end[20];&nbsp;/*&nbsp;shift&nbsp;end&nbsp;*/ 
            <BR>.... <BR>T_report_p-&gt;shift_no='0'; 
            <BR>memcpy(T_report_p-&gt;time_from,"yyyy-mm-dd&nbsp;hh:mi:ss",sizeof(T_report_p-&gt;time_from)); 
            <BR>memcpy(T_report_p-&gt;time_to,"yyyy-mm-dd&nbsp;hh:mi:ss",sizeof(T_report_p-&gt;time_to)); 
            <BR><BR>memset(befehl,&nbsp;'\0',&nbsp;sizeof(befehl)); 
            <BR>sprintf&nbsp;(befehl,&nbsp;"rsh&nbsp;%s&nbsp;%sprot.sh&nbsp;'%s&nbsp;%s&nbsp;%c&nbsp;\"%19.19s\"&nbsp;\"%19.19s\"&nbsp;\"%9.9s\"&nbsp;0'&nbsp;&amp;", 
            <BR>runserver, <BR>REPORT_RSH_PATH, <BR>PROD_LOG, 
            <BR>DRUCKER_NAME_1, <BR>T_report_p-&gt;shift_no, 
            <BR>T_report_p-&gt;time_from, <BR>T_report_p-&gt;time_to, 
            <BR>T_report_p-&gt;coil_id&nbsp;); <BR><BR>system&nbsp;(befehl); 
            <BR><BR>3,产生进程exec()调用例子: <BR><BR><BR>exec() <BR><BR>功能:执行一个文件 
            <BR>语法:#include&nbsp;&lt;unistd.h&gt; 
            <BR>int&nbsp;execl(path,arg0,...,argn,(char*)0) 
            <BR>char&nbsp;*path,*arg0,...,*argn; <BR>int&nbsp;execv(path,argv) 
            <BR>char&nbsp;*path,*argv[]; 
            <BR>int&nbsp;execle(path,arg0,...,argn,(char*)0,envp) 
            <BR>char&nbsp;*path,*arg0,...,*argn,*envp[]; 
            <BR>int&nbsp;execve(path,argv,envp) 
            <BR>char&nbsp;*path,*argv[],*envp[]; <BR>int&nbsp;execvp(file,argv) 
            <BR>char&nbsp;*file,*argv[];[/code:1:d22bc4f5e9] 
            <BR><BR>说明:这是一个系统调用族,&nbsp;用于将一个新的程序调入本进程所占的内存,&nbsp;并覆盖之,&nbsp;产生新的内存进程映象.&nbsp;新的程序可以是可执行文件或SHELL批命令.当C程序被执行时,是如下调用的: 
            <BR>main(int&nbsp;argc,char&nbsp;*argv[],char&nbsp;*envp[]); 
            <BR>  argc是参数个数,是各个参数字符串指针数组,envp是新进程的环境变量字符串的指针数组.argc至少为1,&nbsp;argv[0]为程序文件名,所以,在上面的exec系统调用族中,path为新进程文件的路径名,file为新进程文件名,若file不是全路径名,系统调用会按PATH环境变量自动找对应的可执行文件运行.若新进程文件不是一个可执行的目标文件(如批处理文件),则execlp()和execvp()会将该文件内容作为一个命令解释器的标准输入形成system().arg0,...等指针指向'\0'结束的字符串,组成新进程的有效参数,且该参数列表以一个空指针结束.反过来,arg0至少必须存在并指向新进程文件名或路径名.同样,argv是字符串指针数组,argv[0]指向新进程文件名或路径名,并以一空指针结束.envp是一个字符串指针数组,以空指针结束,这些字符串组成新进程的环境.在调用这些系统调用前打开的文件指针对新进程来说也是打开的,除非它已定义了close-on-exec标志.打开的文件指针在新进程中保持不变,所有相关的文件锁也被保留.调用进程设置并正被捕俘的信号在新进程中被恢复为缺省设置,其它的则保持不变.新进程启动时按文件的SUID和SGID设置定义文件的UID和GID为有效UID和GID.新进程还继承了如下属性: 
            <BR>.&nbsp;附加GID. <BR>.&nbsp;进程号. <BR>.&nbsp;父进程号. <BR>.&nbsp;进程组号. 
            <BR>.&nbsp;会话号. <BR>.&nbsp;控制终端. <BR>.&nbsp;alarm时钟信号剩下的时间. 
            <BR>.&nbsp;当前工作目录. <BR>.&nbsp;根目录. <BR>.&nbsp;文件创建掩码. 
            <BR>.&nbsp;资源限制. <BR>.&nbsp;用户时间,系统时间,子进程用户时间,子进程系统时间. 
            <BR>.&nbsp;记录锁. <BR>.&nbsp;进程信号掩码. <BR>.&nbsp;信号屏蔽. <BR>.&nbsp;优先级. 
            <BR>.&nbsp;预定值. 
            <BR>  调用成功后,系统调用修改新进程文件的最新访问时间.返回值:该系统调用一般不会有成功返回值,&nbsp;因为原来的进程已荡然无存. 
            <BR>例子:printf("now&nbsp;this&nbsp;process&nbsp;will&nbsp;be&nbsp;ps&nbsp;command\n"); 
            <BR>execl("/bin/ps","ps","-ef",NULL); <BR><BR>二、进程通讯编程 
            <BR><BR>[code:1:d22bc4f5e9]1,Message&nbsp;queue队列编程例子 
            <BR><BR>/***************************************************************************** 
            <BR>Excerpt&nbsp;from&nbsp;"Linux&nbsp;Programmer's&nbsp;Guide&nbsp;-&nbsp;Chapter&nbsp;6" 
            <BR>(C)opyright&nbsp;1994-1995,&nbsp;Scott&nbsp;Burkett 
            <BR>*****************************************************************************&nbsp; 
            <BR>MODULE:&nbsp;msgtool.c 
            <BR>***************************************************************************** 
            <BR>A&nbsp;command&nbsp;line&nbsp;tool&nbsp;for&nbsp;tinkering&nbsp;with&nbsp;SysV&nbsp;style&nbsp;Message&nbsp;Queues 
            <BR>*****************************************************************************/ 
            <BR><BR>#include&nbsp;&lt;stdio.h&gt; 
            <BR>#include&nbsp;&lt;stdlib.h&gt; <BR>#include&nbsp;&lt;ctype.h&gt; 
            <BR>#include&nbsp;&lt;sys/types.h&gt; 
            <BR>#include&nbsp;&lt;sys/ipc.h&gt; 
            <BR>#include&nbsp;&lt;sys/msg.h&gt; 
            <BR><BR>#define&nbsp;MAX_SEND_SIZE&nbsp;80 
            <BR><BR>struct&nbsp;mymsgbuf&nbsp;{ <BR>long&nbsp;mtype; 
            <BR>char&nbsp;mtext[MAX_SEND_SIZE]; <BR>}; 
            <BR><BR>void&nbsp;send_message(int&nbsp;qid,&nbsp;struct&nbsp;mymsgbuf&nbsp;*qbuf,&nbsp;long&nbsp;type,&nbsp;char&nbsp;*text); 
            <BR>void&nbsp;read_message(int&nbsp;qid,&nbsp;struct&nbsp;mymsgbuf&nbsp;*qbuf,&nbsp;long&nbsp;type); 
            <BR>void&nbsp;remove_queue(int&nbsp;qid); 
            <BR>void&nbsp;change_queue_mode(int&nbsp;qid,&nbsp;char&nbsp;*mode); 
            <BR>void&nbsp;usage(void); 
            <BR><BR><BR>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;*argv[]) 
            <BR>{ <BR>key_t&nbsp;key; <BR>int&nbsp;msgqueue_id; 
            <BR>struct&nbsp;mymsgbuf&nbsp;qbuf; <BR><BR>if(argc&nbsp;==&nbsp;1) 
            <BR>usage(); 
            <BR><BR>/*&nbsp;Create&nbsp;unique&nbsp;key&nbsp;via&nbsp;call&nbsp;to&nbsp;ftok()&nbsp;*/ 
            <BR>/*&nbsp;key&nbsp;=&nbsp;ftok(".",&nbsp;'w');&nbsp;*/&nbsp; 
            <BR>key&nbsp;=&nbsp;123456; <BR>printf("key=%d\n",key); 
            <BR>key=IPC_PRIVATE; 
            <BR>/*&nbsp;Open&nbsp;the&nbsp;queue&nbsp;-&nbsp;create&nbsp;if&nbsp;necessary&nbsp;*/ 
            <BR><BR>if((tolower(argv[1][0]))!='s') <BR>{ 
            <BR>if((msgqueue_id&nbsp;=&nbsp;msgget(key,&nbsp;IPC_CREAT|0666))&nbsp;==&nbsp;-1)&nbsp;{ 
            <BR>perror("msgget"); <BR>exit(1); <BR>} 
            <BR>printf("msgqueue_id=%d\n",msgqueue_id); <BR>} 
            <BR><BR>switch(tolower(argv[1][0])) <BR>{ 
            <BR>case&nbsp;'s':&nbsp;send_message(atoi(argv[4]),&nbsp;(struct&nbsp;mymsgbuf&nbsp;*)&amp;qbuf, 
            <BR>atol(argv[2]),&nbsp;argv[3]);&nbsp; <BR>break; 
            <BR>case&nbsp;'r':&nbsp;read_message(msgqueue_id,&nbsp;&amp;qbuf,&nbsp;atol(argv[2]));&nbsp; 
            <BR>break; 
            <BR>case&nbsp;'d':&nbsp;remove_queue(atoi(argv[2]));&nbsp; 
            <BR>remove_queue(msgqueue_id); <BR>break;&nbsp; 
            <BR>case&nbsp;'m':&nbsp;change_queue_mode(msgqueue_id,&nbsp;argv[2]);&nbsp; 
            <BR>break; <BR><BR>default:&nbsp;usage(); <BR><BR>} 
            <BR><BR>return(0); <BR>} 
            <BR><BR>void&nbsp;send_message(int&nbsp;qid,&nbsp;struct&nbsp;mymsgbuf&nbsp;*qbuf,&nbsp;long&nbsp;type,&nbsp;char&nbsp;*text) 
            <BR>{ <BR>printf("msgqueue_id=%d\n",qid); 
            <BR>/*&nbsp;Send&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;queue&nbsp;*/ 
            <BR>printf("Sending&nbsp;a&nbsp;message&nbsp;...\n"); 
            <BR>qbuf-&gt;mtype&nbsp;=&nbsp;type; 
            <BR>strcpy(qbuf-&gt;mtext,&nbsp;text); 
            <BR>printf("&nbsp;Type:&nbsp;%ld&nbsp;Text:&nbsp;%s\n",&nbsp;qbuf-&gt;mtype,&nbsp;qbuf-&gt;mtext); 
            <BR><BR>if((msgsnd(qid,&nbsp;(struct&nbsp;msgbuf&nbsp;*)qbuf, 
            <BR>strlen(qbuf-&gt;mtext)+1,&nbsp;0))&nbsp;==-1) <BR>{ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -