- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Linux下的多进程编程
(一)理解Linux下进程的结构
Linux下一个进程在内存里有三部份的数据,就是“数据段”,“堆栈段”和“代
码段”,其实学过汇编语言的人一定知道,一般的CPU象I386,都有上述三种
段寄存器,以方便操作系统的运行。“代码段”,顾名思义,就是存放了程序代码
的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一
个代码段。
堆栈段存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。
而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用m
alloc之类的函数取得的空间)。这其中有许多细节问题,这里限于篇幅就不多
介绍了。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段
和数据段。
(二)如何使用fork
在Linux下产生新的进程的系统调用就是fork函数,这个函数名是英文中“分
叉”的意思。为什么取这个名字呢?因为一个进程在运行中,如果使用了fork,
就产生了另一个进程,于是进程就“分叉”了,所以这个名字取得很形象。下面就
看看如何具体使用fork,这段程序演示了使用fork 的基本框架:
void main(){
int i;
if ( fork() == 0 ) {
/* 子进程程序 */
for ( i = 1; i 1000; i ++ )
printf(This is child process\n);
}
else {
/* 父进程程序*/
for ( i = 1; i 1000; i ++ )
printf(This is process process\n);
}
}
程序运行后,你就能看到屏幕上交替出现子进程与父进程各打印出的一千条
信息了。如果程序还在运行中,你用ps命令就能看到系统中有两个它在运行了。
那么调用这个fork 函数时发生了什么呢?一个程序一调用fork 函数,系统
就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同
一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一
份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦
开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之
间不再有影响了,也就是说,它们之间不再共享任何数据了。而如果两个进程要
共享什么数据的话,就要使用另一套函数 (shmge ,shma ,shmd 等)来操作。
现在,已经是两个进程了,对于父进程,fork 函数返回了子程序的进程号,而对
于子程序,fork 函数则返回零,这样,对于程序,只要判断fork 函数的返回值,
就知道自己是处于父进程还是子进程中。
读者也许会问,如果一个大程序在运行中,它的数据段和堆栈都很大,一次
fork就要复制一次,那么fork 的系统开销不是很大吗?其实UNIX 自有其解决的
办法,大家知道,一般CPU都是 “页”为单位分配空间的,象INTEL的CPU,
其一页在通常情况下是4K字节大小,而无论是数据段还是堆栈段都是由许多
“页”构成的,fork 函数复制这两个段,只是“逻辑”上的,并非“物理”上的,也就是
说,实际执行fork 时,物理空间上两个进程的数据段和堆栈段都还是共享着的,
当有一个进程写了某个数据时,这时两个进程之间的数据才有了区别,系统就将
有区别的“页”从物理上也分开。系统在空间上的开销就可以达到最小。
一个小幽默:下面演示一个足 搞死Linux的小程序,其源代码非常简单:
void main()
{
for(;;) fork();
}
这个程序什么也不做,就是死循环地fork,其结果是程序不断产生进程,而
这些进程又不断产生新的进程,很快,系统的进程就满了,系统就被这么多不断
产生的进程撑死了。用不着是roo,任何人运行上述程序都足以让系统死掉。
哈哈,但这不是Linux不安全的理由,因为只要系统管理员足够聪明,他(或她)
就可以预先给每个用户设置可运行的最大进程数,这样,只要不是roo,任何能
运行的进程数也许不足系统总的能运行和进程数的十分之一,这样,系统管理员
就能对付上述恶意的程序了。
(三)如何启动另一程序的执行
下面我们来看看一个进程如何来启动另一个程序的执行。在Linux中要使用
exec类的函数,exec类的函数不止一个,但大致相同,在Linux中,它们分别
是:execl,execlp,execle,execv,execve和ex
文档评论(0)