fork实例分析
2009-07-27 09:58
274 查看
进程的概念
程序:一个包含可以执行代码的文件,是一个静态的文件。
进程:一个开始执行但是还没有结束的程序的实例,就是可执行文件的具体实现。
为了区分各个不同的进程,系统给每一个进程分配了一个ID以便识别.;
为了充分的利用资源,系统还对进程区分了不同的状态.:将进程分为新建、运行、阻塞、就绪和完成五个状态.。新建表示进程正在被创建,运行是进程正在运行,阻塞是进程正在等待某一个事件发生,就绪是表示系统正在等待CPU来执行命令,而完成表示进程已经结束了系统正在回收资源。
进程的创建 (调用fork函数) :
#include
pid_t fork();
创建:一个进程调用fork以后,系统会创建一个子进程。这个子进程和父进程不同的地方只有他的进程ID和父进程ID。
区分:通过fork的返回值来区分父进程与子进程,当fork掉用失败的时候 (内存不足或者是用户的最大进程数已到)fork返回-1,对于父进程fork返回子进程的ID,而对于fork子进程返回0。
一个子进程建立成功后,这个子进程将和他的父进程运行相同的程式,也就是两者所使用的变量值完全相同,于是子进程和父进程将同步运行一个程式。(各个系统的子进程和父进程的运行先后顺序可能不相同。)
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
main()
{
pid_t pid;
pid=fork();
if (pid < 0)
{
printf("error in fork!/n");
}
else if (pid == 0)
{
printf("i am the child process, my process id is %d/n",getpid());
}
else
{
printf("i am the parent process, my process id is %d/n",getpid());
}
}
运行:
[root@linux]# gcc -o fork1 fork1.c
[root@linux]# ./fork1
i am the child process, my process id is 32050
i am the parent process, my process id is 32049
程序执行:
pid=fork();OS创建一个新进程(子进程),这两个进程共享代码空间,但是数据空间是互相独立的,子程序数据空间的内容是父进程的完整拷贝,指令指针也完全相同,但只有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了,出现了两行结果。至于哪一个最先运行,可能与操作系统有关。
Fork在英文中是叉子,分叉的意思,在函数fork中,取后面的意思。很形象的表示程序从这里分叉,fork函数创建了子进程,子进程和父进程同时(其实是cpu分时处理)开始运行分叉之后的程序。
看看下面一个例子:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int i;
for( i= 0; i< 3; i++)
{
int pid= fork();
if(pid== 0)
{
printf("son/n");
}
else
{
printf("father/n");
}
}
return 0;
}
运行:
[root@linux]# gcc -o fork2 fork2.c
[root@linux]# ./fork2
son
son
father
father
son
father
son
father
son
father
son
father
son
father
共打印出7个father7个son,每一个fork都打印father和son,而每一个father和son也都要进行一次fork,见下图详解:
for i=0 1 2
father father father
son
son father
son
son father father
son
son father
son
其中每一行分别代表一个进程的运行打印结果。当产生子进程的时刻,子进程打印son,当子进程调用fork生成子子进程,它就提升为father。因此,该程序中father永远打印father,son在fork之前是son,fork之后就为father,同时生成新的son。
注:父进程为什么要创建子进程呢?因为 Linux是一个多用户操作系统,在同一时间会有许多的用户在争夺系统的资源,有时进程为了早一点完成任务就创建子进程来争夺资源.,一旦子进程被创建,父子进程一起从fork处继续执行,相互竞争系统的资源,有时候我们希望子进程继续执行,而父进程阻塞直到子进程完成任务,这个时候我们可以调用wait或者waitpid系统调用.。
#include
#include
pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);
wait 系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号。如果没有父进程没有子进程或者他的子进程已经结束wait回立即返回。成功时 (因一个子进程结束)wait将返回子进程的ID,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态。子进程调用 exit、_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值.
WIFEXITED:判断子进程退出值是非0 ;
WEXITSTATUS:判断子进程的退出值(当子进程退出时非0). ;
WIFSIGNALED:子进程由于有没有获得的信号而退出. ;
WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义)。
waitpid 等待指定的子进程直到子进程返回。
pid<-1 等待任何一个组ID等于pid绝对值的任何子进程。
pid=-1 等待任何子进程,相当于wait()。
pid=0 等待任何一个组ID和调用者的组ID相同的进程;
pid>0 等待任何子进程识别码为pid的子进程。
stat_loc和wait的意义一样. options可以决定父进程的状 态.可以取两个值 WNOHANG:父进程立即返回当没有子进程存在时. WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到.
程序:一个包含可以执行代码的文件,是一个静态的文件。
进程:一个开始执行但是还没有结束的程序的实例,就是可执行文件的具体实现。
为了区分各个不同的进程,系统给每一个进程分配了一个ID以便识别.;
为了充分的利用资源,系统还对进程区分了不同的状态.:将进程分为新建、运行、阻塞、就绪和完成五个状态.。新建表示进程正在被创建,运行是进程正在运行,阻塞是进程正在等待某一个事件发生,就绪是表示系统正在等待CPU来执行命令,而完成表示进程已经结束了系统正在回收资源。
进程的创建 (调用fork函数) :
#include
pid_t fork();
创建:一个进程调用fork以后,系统会创建一个子进程。这个子进程和父进程不同的地方只有他的进程ID和父进程ID。
区分:通过fork的返回值来区分父进程与子进程,当fork掉用失败的时候 (内存不足或者是用户的最大进程数已到)fork返回-1,对于父进程fork返回子进程的ID,而对于fork子进程返回0。
一个子进程建立成功后,这个子进程将和他的父进程运行相同的程式,也就是两者所使用的变量值完全相同,于是子进程和父进程将同步运行一个程式。(各个系统的子进程和父进程的运行先后顺序可能不相同。)
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
main()
{
pid_t pid;
pid=fork();
if (pid < 0)
{
printf("error in fork!/n");
}
else if (pid == 0)
{
printf("i am the child process, my process id is %d/n",getpid());
}
else
{
printf("i am the parent process, my process id is %d/n",getpid());
}
}
运行:
[root@linux]# gcc -o fork1 fork1.c
[root@linux]# ./fork1
i am the child process, my process id is 32050
i am the parent process, my process id is 32049
程序执行:
pid=fork();OS创建一个新进程(子进程),这两个进程共享代码空间,但是数据空间是互相独立的,子程序数据空间的内容是父进程的完整拷贝,指令指针也完全相同,但只有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了,出现了两行结果。至于哪一个最先运行,可能与操作系统有关。
Fork在英文中是叉子,分叉的意思,在函数fork中,取后面的意思。很形象的表示程序从这里分叉,fork函数创建了子进程,子进程和父进程同时(其实是cpu分时处理)开始运行分叉之后的程序。
看看下面一个例子:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int i;
for( i= 0; i< 3; i++)
{
int pid= fork();
if(pid== 0)
{
printf("son/n");
}
else
{
printf("father/n");
}
}
return 0;
}
运行:
[root@linux]# gcc -o fork2 fork2.c
[root@linux]# ./fork2
son
son
father
father
son
father
son
father
son
father
son
father
son
father
共打印出7个father7个son,每一个fork都打印father和son,而每一个father和son也都要进行一次fork,见下图详解:
for i=0 1 2
father father father
son
son father
son
son father father
son
son father
son
其中每一行分别代表一个进程的运行打印结果。当产生子进程的时刻,子进程打印son,当子进程调用fork生成子子进程,它就提升为father。因此,该程序中father永远打印father,son在fork之前是son,fork之后就为father,同时生成新的son。
注:父进程为什么要创建子进程呢?因为 Linux是一个多用户操作系统,在同一时间会有许多的用户在争夺系统的资源,有时进程为了早一点完成任务就创建子进程来争夺资源.,一旦子进程被创建,父子进程一起从fork处继续执行,相互竞争系统的资源,有时候我们希望子进程继续执行,而父进程阻塞直到子进程完成任务,这个时候我们可以调用wait或者waitpid系统调用.。
#include
#include
pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);
wait 系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号。如果没有父进程没有子进程或者他的子进程已经结束wait回立即返回。成功时 (因一个子进程结束)wait将返回子进程的ID,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态。子进程调用 exit、_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值.
WIFEXITED:判断子进程退出值是非0 ;
WEXITSTATUS:判断子进程的退出值(当子进程退出时非0). ;
WIFSIGNALED:子进程由于有没有获得的信号而退出. ;
WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义)。
waitpid 等待指定的子进程直到子进程返回。
pid<-1 等待任何一个组ID等于pid绝对值的任何子进程。
pid=-1 等待任何子进程,相当于wait()。
pid=0 等待任何一个组ID和调用者的组ID相同的进程;
pid>0 等待任何子进程识别码为pid的子进程。
stat_loc和wait的意义一样. options可以决定父进程的状 态.可以取两个值 WNOHANG:父进程立即返回当没有子进程存在时. WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到.
相关文章推荐
- Linux中fork()函数实例分析
- Linux中fork()函数实例分析
- fork()-实例分析
- Linux网络编程 fork() 和 exec() 函数实例分析
- 性能测试原理及性能测试实例分析
- JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
- PHP实现事件机制实例分析
- zend framework配置操作数据库实例分析
- PHPMailer使用教程(PHPMailer发送邮件实例分析)
- C#中is和as用法实例分析
- PyQt4 精彩实例分析* 实例11 动态加载Ui
- cocos2d-x高仿捕鱼达人实例分析(一)
- C#实现窗体间传值实例分析
- iPhone企业应用实例分析之三:程序框架分析
- 系统调用分析:fork
- 【协议分析】HTTP2报文头及数据帧格式解析实例分析
- 用户登录安全性的简单实例分析(Cookie、加密)
- Java中的多态用法实例分析
- PHP消息队列用法实例分析
- 实现 | 朴素贝叶斯模型算法研究与实例分析