《unix环境高级编程》通读学习笔记(五)(第13、14章)
上一篇 / 下一篇 2007-08-04 18:06:11 / 个人分类:unix环境高级编程的学习记录
第13章精灵进程
13.1引言
精灵进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时起动,在系统关闭时终止。因为它们没有控制终端,所以说它们是在后台运行的。UNIX系统有很多精灵进程,它们执行日常事物活动。51Testing软件测试网6~M&r%H8|
13.2精灵进程的特征
所有精灵进程都以超级用户(用户ID为0)的优先权运行。没有一个精灵进程具有控制终端—终端名称设置为问号(?)、终端前台进程组ID设置为-1。缺少控制终端可能是精灵进程调用了setsid的结果。除update以外的所有精灵进程都是进程组的首进程,对话期的首进程,而且是这些进程组和对话期中的唯一进程。update是它所在进程组(37)和对话期(37)中的唯一进程,但是该进程组的首进程(可能也是该对话期的首进程)已经终止。最后,应当引起注意的是所有这些精灵进程的父进程都是init进程。
k@,~ it F'p-^:[013.3编程规则
在编写精灵进程程序时需遵循一些基本规则,以便防止产生并不希望的交互作用。51Testing软件测试网)n.Mb3Mbw/}tM(Kj
(1)首先做的是调用fork,然后使父进程exit。51Testing软件测试网gWILQ|f0U|G-r
(2)调用setsid以创建一个新对话期。51Testing软件测试网#| q9M r^&PXfa-v
(3)将当前工作目录更改为根目录。
Xa8h^$wj La0(4)将文件方式创建屏蔽字设置为0。
N?4q-a r9HD4Z7pm0(5)关闭不再需要的文件描述符。51Testing软件测试网@$f,q!?4o~2Bd
13.4出错记录
与精灵进程有关的一个问题是如何处理出错消息。因为它没有控制终端,所以不能只是写到标准出错输出上。需要有一个集中的精灵进程出错记录设施。
q|%r+FG013.4.1 SVR4流log驱动程序
xC5pm#q0SVR4提供了一种流设备驱动程序,其界面具有流出错记录,流事件跟踪以及控制台记录功能。图13-1详细给出了这种设施的整个结构。51Testing软件测试网4l"j9]0eQP w%a
有三个记录进程(logger):出错记录进程、跟踪记录进程以及控制台记录进程。每一条记录消息可以送给其中之一。
9fM2JK%@%R;L013.4.2 4.3+BSD syslog设施
9EU SR-a0自4.2BSD以来,广泛地应用了BSD syslog设施。大多数精灵进程使用这一设施。图13-2显示了syslog设施的详细组织结构。
#PZ:g,P^013.5客户机-服务器模型
精灵进程常常用作为服务器进程。确实,图13-2中,可以称syslogd进程为服务器,用户进程(客户机)用UNIX域数据报套接口向其发送消息。51Testing软件测试网I%g!W$K j9WIr!UoY
一般而言,服务器是一个进程,它等待客户机与其联系,提出某种类型的服务要求。图13-2中,由syslogd服务器提供的服务是记录出错消息。
*G at#sT$cP7i0第14章进程间通信
14.1引言
第8章说明了进程控制原语并且观察了如何调用多个进程。但是这些进程之间交换信息的唯一方法是经由fork或exec传送打开文件,或通过文件系统。本章将说明进程之间相互通信的其他技术—IPC(InterProcess Communication)。
V@Gv,AwS;X yx0UNIX IPC已经是而且继续是各种进程通信方式的统称,其中极少能在所有UNIX的实现中进行移植。表14-1列出了不同实现所支持的不同形式的IPC。51Testing软件测试网/wc-s+|iA
本章将讨论经典的IPC;管道、FIFO、消息队列、信号量以及共享存储器。51Testing软件测试网7y'e5f"K/Car|X
14.2管道
管道是UNIX IPC的最老形式,并且所有UNIX系统都提供此种通信机制,管道有两种限制;
.s#EdE'_B*B.Y0(1)它们是半双工的。数据只能在一个方向上流动。
6p-kof\ A qm9?0(2)它们只能在具有公共祖先的进程之间使用。通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。
c~&d&M+K!A'O0管道是由调用pipe函数而创建的。51Testing软件测试网N!k(h6GrQ
——————————————————————————————————————
R-ISEs!MAK/p+I0#include <unistd.h>51Testing软件测试网%cn NE f0L8sR$s
int pipe(intfiledes[2]) ;
(C*V#B R1?tI c0返回:若成功则为0,若出错则为-151Testing软件测试网jzp/\z[1~*{i*b
有两种方法来描绘一个管道,见图14-1。左半图显示了管道的两端在一个进程中相互连接,右半图则说明数据通过内核在管道中流动。51Testing软件测试网e}&vw3MY"P/|7\
单个进程中的管道几乎没有任何用处。通常,调用pipe的进程接着调用fork,这样就创建了从父进程到子进程或反之的IPC通道。图14-2显示了这种情况。51Testing软件测试网(SgF5GHEQ
fork之后做什么取决于我们想要有的数据流的方向。对于从父进程到子进程的管道,父进程关闭管道的读端(fd[0]),子进程则关闭写端(fd[1])。图14-3显示了描述符的最后安排。51Testing软件测试网a]X(TF;hd
14.3 popen和pclose函数
因为常见的操作是创建一个连接到另一个进程的管道,然后读其输出或向其发送输入,所以标准I/O库为实现这些操作提供了两个函数popen和pclose。这两个函数实现的操作是:创建一个管道,fork一个子进程,关闭管道的不使用端,exec一个shell以执行命令,等待命令终止。
-A5ipnXa ?$}0____________________________________________________________________________
:MGAy!y\%Er0#include <stdio.h>51Testing软件测试网ur'd L;VHv
FILE *popen(const *charcmdstring, const char *type);
N+u-l'S b%T(h&o0返回:若成功则为文件指针,若出错则为NULL51Testing软件测试网6Om c-K3e8C
int pclose(FILE *fp);51Testing软件测试网&q:?8]-l i
返回:cmdstring的终止状态,若出错则为-151Testing软件测试网 A1o8eY*t J'u9lQ
14.4协同进程
UNIX过滤程序从标准输入读取数据,对其进行适当处理后写到标准输出。几个过滤进程通常在shell管道命令中线性地连接。当同一个程序产生某个过滤程序的输入,同时又读取该过滤程序的输出时,则该过滤程序就成为协同进程(coprocess)。51Testing软件测试网'uR.c%f"o']/iB
协同进程的工作方式在C程序中也是非常有用的.
!hv1[bBx$rQY014.5 FIFO
FIFO有时被称为命名管道。管道只能由相关进程使用,它们共同的祖先进程创建了管道。但是,通过FIFO,不相关的进程也能交换数据。
4Y?n:oK["H+X S0第14章已经提及FIFO是一种文件类型。创建FIFO类似于创建文件。确实,FIFO的路径名存在于文件系统中。51Testing软件测试网$wn(mX m~
----------------------------------------------------------------------------------------------------------------------51Testing软件测试网Gi/G[l#].R6O
#include <sys/types.h>51Testing软件测试网IEB u.y6i(\N
#include <sys/stat.h>
u!ApPu S9}W!U0int mkfifo(const *charpathname, mode_tmode);51Testing软件测试网)\\ a$cS6R*D
返回:若成功则为0,若出错则为-1
PC5tv OF3R ^INW0一旦已经用mkfifo创建了一个FIFO,就可用open打开它。确实,一般的文件I/O函数(close、read、write、unlink等)都可用于FIFO。
*C!P zw ?7F-xP0FIFO有两种用途:51Testing软件测试网,l4@9P*? L
(1) FIFO由shell命令使用以便将数据从一条管道线传送到另一条,为此无需创建中间临时文件。
6|G2k"X!|5e G2P:z0(2) FIFO用于客户机-服务器应用程序中,以在客户机和服务器之间传递数据。51Testing软件测试网^TE G2_%t P~y@"~P
14.6系统V IPC
三种系统V IPC:消息队列、信号量以及共享存储器之间有很多相似之处。
+~u3N rs&f f014.6.1标识符和关键字51Testing软件测试网"x |P\sE
每个内核中的IPC结构(消息队列、信号量或共享存储段)都用一个非负整数的标识符(identifier)加以引用。例如,为了对一个消息队列发送或取消息,只需知道其队列标识符。51Testing软件测试网a o8]o:a9UP Iz\
无论何时创建IPC结构(调用msgget、semget或shmget),都应指定一个关键字(key),关键字的数据类型由系统规定为key_t,通常在头文件<sys/types.h>中被规定为长整型。关键字由内核变换成标识符。
wiW ?)e$Od0Q+}014.6.2许可权结构51Testing软件测试网$` M0l @F`.p
系统V IPC为每一个IPC结构设置了一个ipc_perm结构。该结构规定了许可权和所有者。
RO7I Q:D!|8D014.6.3结构限制
q(xI l'Y@|b014.6.4优点和缺点51Testing软件测试网;{{b `HVhG nYT
系统V IPC的主要问题是;IPC结构是在系统范围内起作用的,没有访问计数。51Testing软件测试网Pqv&r ebc\x9]
系统V IPC的另一个问题是;这些IPC结构并不按名字为文件系统所知。我们不能用第3、4章中所述的函数来存取它们或修改它们的特性。为了支持它们不得不增加了十多个全新的系统调用(msgget、semop、shmat等)。我们不能用ls命令见到它们,不能用rm命令删除它们,不能用chmod命令更改它们的存取权。于是,也不得不增加了全新的命令ipcs和ipcrm。51Testing软件测试网sSM0ga%F
因为这些IPC不使用文件描述符,所以不能对它们使用多路转接I/O函数:select和poll。这就使得一次使用多个IPC结构,以及用文件或设备I/O来使用IPC结构很难做到。
!ZL W g4p j!? W"X014.7消息队列
消息队列是消息的链接表,存放在内核中并由消息队列标识符标识。我们将称消息队列为“队列”,其标识符为“队列ID”。msgget用于创建一个新队列或打开一个现存的队列。msgsnd用于将新消息添加到队列尾端。msgrcv用于从队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息。51Testing软件测试网jRdUm%^'j_JV
每个队列都有一个msqid_ds结构与其相关。此结构规定了队列的当前状态。51Testing软件测试网"G{\0]P#k9QM8Eh g
调用的第一个函数通常是msgget,其功能是打开一个现存队列或创建一个新队列。
h+b)L\.X0#include <sys/types.h>51Testing软件测试网YgFc.]"H5AVH p&M:W;K
#include <sys/ipc.h>51Testing软件测试网v't#JT} z
#include <sys/msg.h>51Testing软件测试网,_g$Y0exe1o
int msgget(key_tkey, int flag);51Testing软件测试网:v%f*o%joE
返回:若成功则为消息队列ID,若出错则为-1
tj:D.VPt l0---------------------------------------------------------------------------------------------------------------------
\5A+F0`^2xB-\^0msgctl函数对队列执行多种操作。它以及另外两个与信号量和共享存储有关的函数(semctl和shmctl)是系统V IPC的类似于ioctl的函数(亦即垃圾桶函数)。
|9fV'cC q:p{0---------------------------------------------------------------------------------------------------------------------51Testing软件测试网3Vj9kH)Z#M \
#include <sys/types.h>51Testing软件测试网fV@5t3a2}}
#include <sys/ipc.h>51Testing软件测试网 b-B/PZY
#include <sys/msg.h>
:s%B@;tep5K0int msgctl(intmsqid, int cmd, struct msqid_ds *buf);
&e;`!I3?7n{:R+z4J0返回:若成功则为0,出错则为-151Testing软件测试网kDc&g7T|(_7`
---------------------------------------------------------------------------------------------------------------------51Testing软件测试网S&wwMDGat#a
调用msgsnd将数据放到消息队列上。
z$R6t.`N#o0--------------------------------------------------------------------------------------------------------------------51Testing软件测试网2zuw q3TF#lv
#include <sys/types.h>
$m`4M!Z-G,@;a5_0#include <sys/ipc.h>51Testing软件测试网\a NG]k
#include <sys/msg.h>51Testing软件测试网1mD+|'hT,H'e:e
int msgsnd(intmsqid, const void *ptr, size_tnbytes, int flag)
pn.tlDTy0返回:若成功则为0,若出错则为-1
Hm j'Z#A+gj1D*?0---------------------------------------------------------------------------------------------------------------------51Testing软件测试网TxO)YGA? @
msgrcv从队列中取用消息。51Testing软件测试网5S bt o u3~
--------------------------------------------------------------------------------------------------------------------51Testing软件测试网o|5hCB~:_
#include <sys/types.h>51Testing软件测试网t&P e|.E
#include <sys/ipc.h>
kg{3v6{2o(B0#include <sys/msg.h>
kg&uN4\7r.`W!B5W0int msgrcv(intmsqid, void * ptr , size_t nbytes, long type, int flag);
qWNO%p L)?F0返回:若成功则为消息数据部分的长度,若出错则为-1
E3R0S n^BB0---------------------------------------------------------------------------------------------------------------------51Testing软件测试网*xbe VS0[O0Bb V
<
TAG:
我的栏目
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | 5 | 6 | ||||
7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
28 | 29 | 30 |
我的存档
数据统计
- 访问量: 158648
- 日志数: 220
- 图片数: 4
- 文件数: 1
- 书签数: 16
- 建立时间: 2007-04-27
- 更新时间: 2012-01-30