资源预览内容
第1页 / 共55页
第2页 / 共55页
第3页 / 共55页
第4页 / 共55页
第5页 / 共55页
第6页 / 共55页
第7页 / 共55页
第8页 / 共55页
第9页 / 共55页
第10页 / 共55页
亲,该文档总共55页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第10章 UNIX系统的进程通信,进程是在特定的环境中执行的 进程执行中需要进行进程间的协调 进程间的协调机制是进程通信 本章描述UNIX进程通信的机制和方法,进程通信基本概念,进程通信随着相关技术的发展不断增加复杂化度、灵活性,通常包括控制信息传递和大批量信息传递。 1. 通信方式 1) 主从式-通信进程间有主从之分 2) 会话式-用请求/服务方式完成通信 3) 消息或邮箱机制-通过消息缓冲或邮箱完成通信 4) 共享存储区通信-通过共享缓冲区通信,2. Unix中进程通信包括三种: .基本通信用于传递进程间的控制信息; .管道通信将管道文件作为通信的介质,传递进程间的信息; .IPC(Inter Process Commuation)通信用于进程间大量的数据传送。,UNIX基本通信,1. 锁文件通信 通信进程双方将某个文件的建立与撤消作为一个锁标志,即约定:在某个指定目录中(通常会是/tmp目录)查找是否有一个双方约定好的锁文件存在。 存在时完成一种处理 不存在时完成另一种操作,例: 两进程P1和P2试图访问一个不能同时进入的临界资源打印机时,设定一个锁文件,执行中: P1查询锁文件是否存在,若不存在P1创建锁文件lock_file,然后使用该资源; 使用完后释放该资源并删除lock_file; 如锁文件存在P1等待一个时间再进行锁文件的查询。 P2也执行与P1相似动作达到对共享临界资源的访问。 可以用系统调用creat、unlink及库函数sleep完成,2. 用记录/文件锁定进行通信 通过对文件或文件中的记录锁定实现通信,在UNIX中有一些加锁的系统调用和函数,可实现: 建议型锁定-文件/记录可被锁定,进程执行时访问判断锁定的位置,决定是否能执行相应的访问。 例:多个进程对某文件都具有访问权,通过对文件锁定位置的判别,实现进程间的合作,并访问文件内容。 这种锁对rogue(诬赖)进程没有控制。,强制型锁定-确定一个锁协议,提供附加的安全性。即对文件做每一个read及write系统调用时检测锁信息,满足时访问,否则不能访问(包括rogue 进程)。 例: 如某文本文件x.dat(不可执行),它对某进程组ID=12的进程开放,同时用chmod关闭进程组ID=12的执行位,构成强制型锁定。 通过系统调用fcntl及库函数lockf可完成文件中记录的锁定。,系统调用fcntl: 功能:对文件或文件中部分内容进行锁定。 头文件:, 调用方式:int fcntl(int fid, int cmd, *arg*); 参数说明: fid有效的整数,表示已打开的文件描述符 cmd整数值,说明fcntl完成的行为,在头文件fcntl.h中 *arg*选项,若采用锁时引用了一个flock结构,fcntl.h中定义的常量: F_SETLK: 设置或删除一个锁定,行为基于flock结构 F_SETLKW: 与F_SETLK相同,但记录不可用时阻塞 F_GETLK: 通过flock结构返回锁定状态信息,第三个参数引用的flock结构: typedef struct flock short l_type; /*锁定类型*/ short l_whence; /*开始位置*/ off_t l_start; /*相对位移*/ off_t l_len; /*长度(0=文件尾)*/ long l_sysid; /分布的进程ID,适应分布体系*/ pid_t l_pid; /与文件相关的进程ID*/ long pad4; /*备用*/ flock_t;,信号,信号的概念 signal函数 发送一个信号 kill, raise alarm和pause函数 可靠的信号机制,信号的概念,Signal 软中断 处理异步事件的机制 每个信号有一个名字(以SIG开头) 定义为一个整数 () 如何产生一个信号 按终端键,硬件异常,kill(2)函数,kill(1)命令,软件条件,.,Linux/UNIX中的信号,Signals in Linux/UNIX (contd),信号处理,忽略信号 不能忽略的信号: SIGKILL, SIGSTOP 一些硬件异常信号 执行系统默认动作 捕捉信号,signal函数,改变指定signum信号的处理方式. #include typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); (返回值: 如果成功则返回先前的handler,否则返回SIG_ERR) “handler”: 用户定义的函数,或 SIG_DEF,或 SIG_IGN,signal函数(contd),程序示例 static void sig_usr(int); int main(void) if (signal(SIGUSR1, sig_usr) = SIG_ERR) err_sys(“cant catch SIGUSR1“); if (signal(SIGUSR2, sig_usr) = SIG_ERR) err_sys(“cant catch SIGUSR2“); for ( ; ; ) pause(); ,发送一个信号,kill(): 给一个进程发送一个信号 #include #include int kill(pid_t pid, int sig); (返回值: 成功为0, 否则为-1) raise(): 给当前进程发送一个信号 #include int raise(int sig); (返回值: 成功为0, 否则为-1),alarm和pause函数,alarm: 设置时钟信号 #include unsigned int alarm(unsigned int seconds); (Returned value: 0, or the number of seconds remaining of previous alarm) pause: 等待一个信号 #include int pause(void); (Returned value: -1, errno is set to be EINTR),alarm和pause函数,程序示例 sleep函数的实现 unsigned int sleep1(unsigned int nsecs) if ( signal(SIGALRM, sig_alrm) = SIG_ERR) return(nsecs); alarm(nsecs); /* 开始计时 */ pause(); /*定时信号来时被唤醒*/ return(alarm(0) ); /*关闭定时器 */ ,可能出现的问题,与时间有关的问题 竞争条件 中断的系统调用 可重入问题,可靠的信号机制,Weakness of the signal function Signal block signal mask Signal set sigset_t data type Signal handling functions using signal set sigprocmask, sigaction, sigpending, sigsuspend,signal set operations,#include int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signum); int sigdelset(sigset_t *set, int signum); (Return value: 0 if success, -1 if error) int sigismember(const sigset_t *set, int signum); (Return value: 1 if true, 0 if false),sigprocmask 函数,检测或更改(或两者)进程的信号掩码 #include sigprocmask(int how, const sigset_t *set, sigset_t *oldset); (Return Value: 0 is success, -1 if failure) 参数“how”决定对信号掩码的操作 SIG_BLOCK: 将set中的信号添加到信号掩码(并集) SIG_UNBLOCK: 从信号掩码中去掉set中的信号(差集) SIG_SETMASK: 把信号掩码设置为set中的信号 例外: SIGKILL, SIGSTOP,sigpending 函数,返回当前未决的信号集 #include sigpending(sigset_t *set); (Returned Value: 0 is success, -1 if failure),sigaction 函数,检查或修改(或两者)与指定信号关联的处理动作 #include sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); (Returned Value: 0 is success, -1 if failure) struct sigaction至少包含以下成员: handler_t sa_handler; /* addr of signal handler, or SIG_IGN, or SIG_DEL */ sigset_t sa_mask; /* additional signals to block */ int sa_flags; /* signal options */,sigsuspend 函数,用sigmask临时替换信号掩码,在捕捉一个信号或发生终止该进程的信号前,进程挂起。 #include sigsuspend(const sigset *sigmask); (Returned value: -1, errno is set to be EINTR) sigsuspend和pause,signal function review,用sigaction实现signal函数 Sigfunc * signal(int signo, handler_t func) struct sigaction act, oact; act.sa_handler = func; sigemptyset( ,管道通信,UNIX中管道是FIFO的特殊文件,文件大小相对固定,通常定义为10个逻辑块,每个逻辑块大小为512字节。头文件或中常量PIPE_BUF是描述管道缓冲区可容纳的最大字节数的信息。 通过对管道的读/写,实现进程间的通信。,1.管道读/写特点 1)对管道写与对文件写的区别 对管道写操作,内容附加在管道的末端;对文件的写不遵守这条规定,可通过调整指针随意进行。 对管道写时一次写入的字节数最好不大于设定的系统常量PIPE_BUF的值;对文件写则不必遵守此项规则。 当试图对一个没有被进程打开用做写的管道进行write操作时,将生成SIGPIPE信号,并且系统公用变量errno的值被置成EPIPE,表示管道被破坏。,2)对管道读与对文件读操作的区别 对管道读时,所有的read调用总是从管道当前位置开始;而对文件的读可以支持文件访问指针的移动。 当管道中无信息时read调用进程被阻塞,但对空文件读时可返回空串并不发生进程阻塞。 如果管道未被其它进程以写方式打开,则对管道做read系统调用时返回0。,2. 无名管道通信 无名管道由系统调用pipe创建,生成两个整形文件描述符filedes0和filedes1分别指向两个数据流。管道有全双工和半双工之分。 pipe系统调用格式: status=p
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号