泛泛的读了这本书的前两章,了解了UNIX的一些基础性的知识,Chapter 1 中有些知识比如创建子进程fork()的知识一开始还不是很懂,以前根本就真正没有理解和体会过子进程的概念,相信很多UNIX初学者,如果没有学过OS的话,可能也会在fork()这个函数(应该叫系统调用,准确的来说)上有所迷惑,比如如下代码:
#include "unistd.h" #include "stdio.h" int main(int argc,char *argv[]) {
int p1;
int test_number=0;
if((p1=fork())==-1)
{
printf("Fork failed...\n");
return 0;
}
else
{
if(p1==0)
{
test_number++;
printf("Child process p1 is runing,test_number=%d\n",test_number);
}
else
{
test_number++;
printf("Parent process is runing,test_number=%d\n",test_number); }
}
return 0; }
|
compile->run
我们可以看到打印的结果如下:
[moon@localhost Cfiles]$ gcc test_Fork.c -o test_Fork [moon@localhost Cfiles]$ ./test_Fork
Parent process is runing,test_number=1 [moon@localhost Cfiles]$ Child process p1 is runing,test_number=1 [moon@localhost Cfiles]$ ./test_Fork
Child process p1 is runing,test_number=1
Parent process is runing,test_number=1
[moon@localhost Cfiles]$
|
这里我们运行了./test_Fork两次,第上次先打印了父进程的输出,再打印出子进程的输出,而第二次运行的时候却又发现顺序反过来了,第一次运行这个程序的时候,很头痛,且不说这个打印顺序的问题,而我们奇怪的是为什么if 和 else都 执行了```对,它们都执行了,下面就我个人的理解来剖析一下这个程序:
从
if((p1=fork())==-1)这里看起。 首先,我们通过 fork() 这个系统调用来创建一个新的子进程,fork()函数有三种返回值,分别是:-1(表示子进程创建失败)、0(子进程给自己的一个返回值)、大于0(这个大于0的数,我们不能确定,这是子进程返回给父进程的PID)。如果fork()调用成功,
那么新产生的子进程就会得到一份父进程的数据区拷贝,但会和父进程共享代码区,两个进程各自维护自己的数据区,这里注意的是在子进程里fork()会返回0,于是子进程里p1=0,而fork()返回其pid给了父进程,于是父进程里p1>0 (p1=子进程的PID)。接下来两个进程在处理机的调度算法下开始同步执行,也正是因为处理机调度的原因,使得两次输出的结果不同,而且我们可以看到第一次的输出:
[moon@localhost Cfiles]$ Child process p1 is runing,test_number=1 子进程
输出在shell命令符之后,这是因为我们没有对STDOUT加锁的缘固,再者可能有人会问,为什么没有出现
形如:Child process p1 is
[moon@localhost Cfiles]$ runing,test_number=1一类的杂乱输出呢,这个问题我还没有去仔细琢磨,在印象里好像是因为标准I/O是带缓冲机制的,而且是行缓冲,所以像
"Child process p1 is runing,test_number=1" 这样一行信息是不会被隔断的。
阅读(1479) | 评论(0) | 转发(0) |