Unix 多进程编程.doc
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《Unix 多进程编程.doc》由会员分享,可在线阅读,更多相关《Unix 多进程编程.doc(28页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、一.多进程程序的特点 由于UNIX系统是分时多用户系统, CPU按时间片分配给各个用户使用, 而在实质上应该说CPU按时间片分配给各个进程使用, 每个进程都有自己的运行环境以使得在CPU做进程切换时不会忘记该进程已计算了一半的半成品. 以DOS的概念来说, 进程的切换都是一次DOS中断处理过程, 包括三个层次: (1)用户数据的保存: 包括正文段(TEXT), 数据段(DATA,BSS), 栈段(STACK), 共享内存段(SHARED MEMORY)的保存. (2)寄存器数据的保存: 包括PC(program counter,指向下一条要执行的指令的地址), PSW(processor st
2、atus word,处理机状态字), SP(stackpointer,栈指针), PCBP(pointer of process control block,进程控制块指针), FP(frame pointer,指向栈中一个函数的local变量的首地址), AP(augument pointer,指向栈中函数调用的实参位置), ISP(interrupt stack pointer,中断栈指针), 以及其他的通用寄存器等. (3)系统层次的保存: 包括proc,u,虚拟存储空间管理表格,中断处理栈. 以便于该进程再一次得到CPU时间片时能正常运行下去. 既然系统已经处理好所有这些中断处理的过程
3、, 我们做程序还有什么要担 心的呢? 我们尽可以使用系统提供的多进程的特点, 让几个程序精诚合作, 简 单而又高效地把结果给它搞出来. 另外,UNIX系统本身也是用C语言写的多进程程序,多进程编程是UNIX的特 点,当我们熟悉了多进程编程后,将会对UNIX系统机制有一个较深的认识. 首先我介绍一下多进程程序的一些突出的特点: 1.并行化 一件复杂的事件是可以分解成若干个简单事件来解决的, 这在程序员 的大脑中早就形成了这种概念, 首先将问题分解成一个个小问题, 将小问 题再细分, 最后在一个合适的规模上做成一个函数. 在软件工程中也是这 么说的. 如果我们以图的方式来思考, 一些小问题的计算是
4、可以互不干扰 的, 可以同时处理, 而在关键点则需要统一在一个地方来处理, 这样程序 的运行就是并行的, 至少从人的时间观念上来说是这样的. 而每个小问题 的计算又是较简单的. 2.简单有序 这样的程序对程序员来说不亚于管理一班人, 程序员为每个进程设计 好相应的功能, 并通过一定的通讯机制将它们有机地结合在一起, 对每个 进程的设计是简单的, 只在总控部分小心应付(其实也是蛮简单的), 就可 完成整个程序的施工. 3.互不干扰 这个特点是操作系统的特点, 各个进程是独立的, 不会串位. 4.事务化 比如在一个数据电话查询系统中, 将程序设计成一个进程只处理一次 查询即可, 即完成一个事务.
5、当电话查询开始时, 产生这样一个进程对付 这次查询; 另一个电话进来时, 主控程序又产生一个这样的进程对付, 每 个进程完成查询任务后消失. 这样的编程多简单, 只要做一次查询的程序 就可以了. 二.常用的多进程编程的系统调用 1.fork() 功能:创建一个新的进程. 语法:#include #include pid_t fork(); 说明:本系统调用产生一个新的进程, 叫子进程, 是调用进程的一个复 制品. 调用进程叫父进程, 子进程继承了父进程的几乎所有的属 性: . 实际UID,GID和有效UID,GID. . 环境变量. . 附加GID. . 调用exec()时的关闭标志. . U
6、ID设置模式比特位. . GID设置模式比特位. . 进程组号. . 会话ID. . 控制终端. . 当前工作目录. . 根目录. . 文件创建掩码UMASK. . 文件长度限制ULIMIT. . 预定值, 如优先级和任何其他的进程预定参数, 根据种类不同 决定是否可以继承. . 还有一些其它属性. 但子进程也有与父进程不同的属性: . 进程号, 子进程号不同与任何一个活动的进程组号. . 父进程号. . 子进程继承父进程的文件描述符或流时, 具有自己的一个拷贝 并且与父进程和其它子进程共享该资源. . 子进程的用户时间和系统时间被初始化为0. . 子进程的超时时钟设置为0. . 子进程的信号
7、处理函数指针组置为空. . 子进程不继承父进程的记录锁. 返回值: 调用成功则对子进程返回0, 对父进程返回子进程号, 这也是 最方便的区分父子进程的方法. 若调用失败则返回-1给父进程, 子进程不生成. 例子:pid_t pid; if (pid=fork()0) /*父进程处理过程*/ else if (pid=0) /*子进程处理过程*/ exit(0); /*注意子进程必须用exit()退出运行*/ else printf(fork errorn); exit(0); 2.system() 功能:产生一个新的进程, 子进程执行指定的命令. 语法:#include #include in
8、t system(string) char *string; 说明:本调用将参数string传递给一个命令解释器(一般为sh)执行, 即 string被解释为一条命令, 由sh执行该命令.若参数string为一 个空指针则为检查命令解释器是否存在. 该命令可以同命令行命令相同形式, 但由于命令做为一个参数放 在系统调用中, 应注意编译时对特殊意义字符的处理. 命令的查 找是按PATH环境变量的定义的. 命令所生成的后果一般不会对父 进程造成影响. 返回值:当参数为空指针时, 只有当命令解释器有效时返回值为非零. 若参数不为空指针, 返回值为该命令的返回状态(同waitpid() 的返回值. 命
9、令无效或语法错误则返回非零值,所执行的命令被 终止. 其他情况则返回-1. 例子:char command81; int i; for (i=1;i0) wait(int *)0); /*父进程等待子进程的返回*/ else /*子进程处理过程*/ exit(0); 7.waitpid() 功能:等待指定进程号的子进程的返回并修改状态 语法:#include #include pid_t waitpid(pid,stat_loc,options) pid_t pid; int *stat_loc,options; 说明:当pid等于-1,options等于0时,该系统调用等同于wait().否
10、则该 系统调用的行为由参数pid和options决定. pid指定了一组父进程要求知道其状态的子进程: -1:要求知道任何一个子进程的返回状态. 0:要求知道进程号为pid值的子进程的状态. 0) waitpid(pid,&stat_loc,0); /*父进程等待进程号为pid的子进程的返回*/ else /*子进程的处理过程*/ exit(1); /*父进程*/ printf(stat_loc is %dn,stat_loc); /*字符串stat_loc is 1将被打印出来*/ 8.setpgrp() 功能:设置进程组号和会话号. 语法:#include pid_t setpgrp()
11、说明:若调用进程不是会话首进程.将进程组号和会话号都设置为与它 的进程号相等.并释放调用进程的控制终端. 返回值:调用成功后,返回新的进程组号. 例子:/*父进程处理*/ if (fork()0) /*父进程处理*/ else setpgrp(); /*子进程的进程组号已修改成与它的进程号相同*/ exit(0); 9.exit() 功能:终止进程. 语法:#include void exit(status) int status; 说明:调用进程被该系统调用终止.引起附加的处理在进程被终止前全 部结束. 返回值:无 10.signal() 功能:信号管理功能 语法:#include void
12、 (*signal(sig,disp)(int) int sig; void (*disp)(int); void (*sigset(sig,disp)(int) int sig; void (*disp)(int); int sighold(sig) int sig; int sigrelse(sig) int sig; int sigignore(sig) int sig; int sigpause(sig) int sig; 说明:这些系统调用提供了应用程序对指定信号的简单的信号处理. signal()和sigset()用于修改信号定位.参数sig指定信号(除了 SIGKILL和SIGS
13、TOP,这两种信号由系统处理,用户程序不能捕捉到). disp指定新的信号定位,即新的信号处理函数指针.可以为 SIG_IGN,SIG_DFL或信号句柄地址. 若使用signal(),disp是信号句柄地址,sig不能为SIGILL,SIGTRAP 或SIGPWR,收到该信号时,系统首先将重置sig的信号句柄为SIG_DFL, 然后执行信号句柄. 若使用sigset(),disp是信号句柄地址,该信号时,系统首先将该 信号加入调用进程的信号掩码中,然后执行信号句柄.当信号句柄 运行结束 后,系统将恢复调用进程的信号掩码为信号收到前的状态.另外, 使用sigset()时,disp为SIG_HOL
14、D,则该信号将会加入调用进程的 信号掩码中而信号的定位不变. sighold()将信号加入调用进程的信号掩码中. sigrelse()将信号从调用进程的信号掩码中删除. sigignore()将信号的定位设置为SIG_IGN. sigpause()将信号从调用进程的信号掩码中删除,同时挂起调用 进程直到收到信号. 若信号SIGCHLD的信号定位为SIG_IGN,则调用进程的子进程在终 止时不会变成僵死进程.调用进程也不用等待子进程返回并做相 应处理. 返回值:调用成功则signal()返回最近调用signal()设置的disp的值. 否则返回SIG_ERR. 例子一:设置用户自己的信号中断处理
15、函数,以SIGINT信号为例: int flag=0; void myself() flag=1; printf(get signal SIGINTn); /*若要重新设置SIGINT信号中断处理函数为本函数则执行以 *下步骤*/ void (*a)(); a=myself; signal(SIGINT,a); flag=2; main() while (1) sleep(2000); /*等待中断信号*/ if (flag=1) printf(skip system call sleepn); exit(0); if (flag=2) printf(skip system call slee
16、pn); printf(waiting for next signaln); 11.kill() 功能:向一个或一组进程发送一个信号. 语法:#include #include int kill(pid,sig); pid_t pid; int sig; 说明:本系统调用向一个或一组进程发送一个信号,该信号由参数sig指 定,为系统给出的信号表中的一个.若为0(空信号)则检查错误但 实际上并没有发送信号,用于检查pid的有效性. pid指定将要被发送信号的进程或进程组.pid若大于0,则信号将 被发送到进程号等于pid的进程;若pid等于0则信号将被发送到所 有的与发送信号进程同在一个进程组的
17、进程(系统的特殊进程除 外);若pid小于-1,则信号将被发送到所有进程组号与pid绝对值 相同的进程;若pid等于-1,则信号将被发送到所有的进程(特殊系 统进程除外). 信号要发送到指定的进程,首先调用进程必须有对该进程发送信 号的权限.若调用进程有合适的优先级则具备有权限.若调用进程 的实际或有效的UID等于接收信号的进程的实际UID或用setuid() 系统调用设置的UID,或sig等于SIGCONT同时收发双方进程的会话 号相同,则调用进程也有发送信号的权限. 若进程有发送信号到pid指定的任何一个进程的权限则调用成功, 否则调用失败,没有信号发出. 返回值:调用成功则返回0,否则返
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Unix 多进程编程 进程 编程
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内