教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 资格考试 >

c语言多进程多线程编程(6)

来源:网络收集 时间:2026-05-18
导读: if ((int)area1==-1) { printf(\ exit(1); } /*取得共享数据段area1的版本号*/ v=sdgetv(area1); /*申请访问共享数据段area1,若已有进程在访问该段则本进程挂 *起,否则进入访问并将该数据段加写锁*/ sdenter(area1,

if ((int)area1==-1) {

printf(\ exit(1); }

/*取得共享数据段area1的版本号*/

v=sdgetv(area1);

/*申请访问共享数据段area1,若已有进程在访问该段则本进程挂 *起,否则进入访问并将该数据段加写锁*/ sdenter(area1,SD_WRITE);

/*对共享数据段访问,写10个a*/

strcpy(area1,\

/*申请解除访问权限,若已有进程申请访问则激活该进程*/ sdleave(area1); /*进程处理过程*/

/*等待取共享数据段area1的版本号*/ sdwaitv(area1,v);

/*重新申请访问共享数据段area1*/ sdenter(area1,SD_WRITE); /*读取共享数据段中的数据*/

memcpy(buf,area1,20);

/*申请解除访问权限,若已有进程申请访问则激活该进程*/ sdleave(area1);

printf(\

2.31.getenv() 取得指定环境变量值

功能:取得指定环境变量值. 语法:

#include #include char *getenv(name) char *name;

说明:本系统调用检查环境字符串(格式如name=\并在找到有指\定名字的环境值后,返回指向value字符串的指针.否则返回空指 针. 返回值:如前述. 例子:

char * value;

value=getenv(\

printf(\将打印出HOME环境变量的值*/

2.32.putenv() 修改或增加环境值

功能:修改或增加环境值.

语法:

#include int putenv(string) char *string;

说明:参数string指向一个字符串,格式如下:

name=value

本系统调用将环境变量name等于值value,修改或增加一个环境变 量,字符串string成为环境的一部分.

返回值:若putenv()不能取得合适的内存空间则返回非0值,否则返回0. 例子:/*父进程处理*/

putenv(\ putenv(\TH=/bin\ if (fork()>0)

exit(0); /*父进程退出运行*/ /*子进程处理*/

setpgrp();

/*父进程设置的环境变量已传到子进程*/ char * value1;

value1=getenv(\ value2=getenv(\TH\

printf(\TH=[%s]\\n\ /*将打印出\和\TH=/bin\

三.多进程编程技巧

3.1.主要程序结构 3.1.1事件主控方式

若是应用程序属于事务处理方式,则在主函数中设计为监控事件发生, 当事件发生时,可以生成一个新的进程来处理该事务,事务处理完成后就 可以让子进程退出系统.这种处理方式一般不要消息传递.

3.1.2信息协调方式

若是应用程序需要由多个进程协调处理完成,则可以生成这些进程, 通过消息在进程间的传递,使各个进程能相互协调,共同完成事务.这种处理方式一般是用fork()生成几个进程后,用exec()调用其它程序文件,使得不同的程序同时在系统内运行.然后通过IPC机制传送消息,使各个程序能协调运行.

3.2.选择主体分叉点 3.2.1事件初始产生

对应于事件主控方式的程序结构.关键点在于以何种方式选择事件的初始发生点,如网络程序给出的建链信息.主控程序在收到该消息后就认为是一个事件开始,则可以产生一个子进程处理后面的事务:接收交易信息,事务处理,发送返回交易信息,关闭链接等,完成后将子进程退出系统.

3.2.2主程序自主产生

对应于信息协调方式的程序结构.主控程序只负责生成几个子进程,各个子进程分别调用exec()将不同的执行文件调入内存运行,主控程序在生成所有的子进程后即可退出系统,将子进程留在内存中运行.

3.3.进程间关系处理 3.3.1父子进程关系

. 进程组处理

进程组的概念是这样的,当系统启动时,第一个进程是init,其进程 组号等于进程号,由它产生的所有子进程的进程组号也相同,子进程 的子进程也继承该进程组号,这样,由init所生成的所有子进程都属 于同一个进程组.但是,同一个进程组的父子进程可能在信号上有相 互通讯,若父进程先于子进程退出系统,则子进程会成为一个孤儿进 程,可能变成僵死进程.从而使该子进程在其不\愿意\的情况下退出 运行.为解决这个问题,子进程可以自己组成一个新的进程组,即调 用setpgrp()与原进程组脱离关系,产生一个新的进程组,进程组号 与它的进程号相同.这样,父进程退出运行后就不会影响子进程的当 前运行.

. 子进程信号处理

但是,单做上述处理还不能解决另一个困难,即子进程在退出运行 时,找不到其父进程(父进程已退出,子进程的父进程号改为1).发送 子进程退出信号后没有父进程做出响应处理,该子进程就不可能完 全退出运行,可能进入僵死状态.所以父进程在产生子进程前最好屏 蔽子进程返回信号的处理,生成子进程,在父进程退出运行后,子进 程返回则其进程返回信号的处理会由系统给出缺省处理,子进程就 可以正常退出.

3.3.2兄弟进程关系

. 交换进程号

对于信息协调方式的程序来说,各兄弟进程间十分需要相互了解进 程号,以便于信号处理机制.比较合理的方法是父进程生成一个共享 内存的空间,每个子进程都在启动时在共享内存中设置自己的进程 号.这样,当一个子进程要向另一个子进程发送信号或是因为其他原 因需要知道另一个子进程号时,就可以在共享内存中访问得到所需 要的进程号.

3.3.3僵尸进程及如何处理子进程死亡

3.3.3.1僵尸进程

僵尸(Zombie)进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。

当一个进程已退出,但其父进程还没有调用系统调用wait(稍后介绍)对其进行收集之前的这段时间里,它会一直保持僵尸状态。

僵尸进程的概念是从UNIX上继承来的,而UNIX的先驱们设计这个东西并非是因为闲来无聊想烦烦其他的程序员。僵尸进程中保存着很多对程序员和系统管理员非常重要的信息,首先,这个进程是怎么死亡的?是正常退出呢,还是出现了错误,还是被其它进程强迫退出的?其次,这个进程占用的总系统CPU时间和总用户CPU时间分别是多少?发生页错误的数目和收到信号的数目。这些信息都被存储在僵尸进程中,试想如果没有僵尸进程,进程一退出,所有与之相关的信息都立刻归于无形,而此时程序员或系统管理员需要用到,就只好干瞪眼了。

收集这些信息,并终结这些僵尸进程靠waitpid调用和wait调用等方法完成。 僵尸进程虽然对其他进程几乎没有什么影响,不占用CPU时间,消耗的内存也几乎可以忽略不计,但有它在那里呆着,还是让人觉得心里很不舒服,同时Linux系统中进程数目是有限制的,在一些特殊的情况下,如果存在太多的僵尸进程,也会影响到新进程的产生。

for(int i=0;i<10;i++) if( fork==0) exit(0);

3.3.3.2处理子进程死亡的四种方法

3.3.3.2.1 忽略SIGCHLD信号.(只在Linux使用);

struct sigaction act,oldact; act.sa_handler=SIG_IGN; sigemptyset(&act.sa_mask); act.sa_flags=0;

if(sigaction(SIGCHLD,&act,&oldact)<0)

exit(1);

内核负责清除进程表项。(Linux only)

3.3.3.2.2 调用wait()或waitpid(); pid_t wait(int* statloc);

pid_t waitpid(pid_t pid,int* statloc,int option);

前者等待任意一个子进程结束, …… 此处隐藏:2826字,全部文档内容请下载后查看。喜欢就下载吧 ……

c语言多进程多线程编程(6).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/412793.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)