第八章相关

fork()函数:

(1)fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

(2)一次调用,两次返回。如果返回值为0,则表示当前子进程中;若大于0,则说明在父进程中,返回值为父进程的pid。

程序进程图画法:进程图是刻画程序语句的偏序的一种简单的前驱图。每个顶点a对应一条程序语句的执行,有向边a->b表示语句a发生在语句b之前。边上可以标注出一些信息。每张图从一个顶点开始,对应于调用main的父进程,每个进程的顶点序列结束于一个对应于exit调用的顶点。这个顶点只有入边,没有出边。

例:

void fork0() 
{
    if (fork() == 0) {
	printf("Hello from child\n");
    }
    else {
	printf("Hello from parent\n");
    }
}

 运行结果:

分析:

fork函数,调用一次,返回两次,这个运行结果可以很直观看出这一特点。

代码1

void fork2()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("Bye\n");
}

运行结果:

简单分析进程图:

可理解输出结果。

代码2

void fork3()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("L2\n");    
    fork();
    printf("Bye\n");
}

运行结果:

同样分析进程图即可。

代码3:

#include "csapp.h"

/* $begin fork */
/* $begin wasidefork */
int main(int argc, char *argv[]) 
{
    pid_t pid;
    int x = 1;

    pid = Fork(); //line:ecf:forkreturn
    if (pid == 0) {  /* Child */
	printf("child : x=%d\n", ++x); 
	printf("child : x=%d\n", ++x); 
	fflush(stdout);
	return 0;
    }

    /* Parent */
    printf("parent: x=%d\n", --x);
    printf("parent: x=%d\n", --x);
    fflush(stdout);
    return 0;
}
/* $end fork */
/* $end wasidefork */

运行结果:

 

ffiush()函数:清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件。

如果成功刷新,fflush返回0。指定的流没有缓冲区或者只读打开时也返回0值。返回EOF指出一个错误。

注意:如果fflush返回EOF,数据可能由于写错误已经丢失。当设置一个重要错误处理器时,最安全的是用setvbuf函数关闭缓冲或者使用低级I/0例程,如open、close和write来代替流I/O函数。

结果分析: 根据进程,父进程走两个减,子进程走两个加,输出结果如图

 一些关于进程的函数

wait()函数:如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。

waitpid的返回值比wait稍微复杂一些,一共有3种情况:

          1、当正常返回的时候,waitpid返回收集到的子进程的进程ID;

          2、如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;

          3、如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;

 

 

 两个宏

1、WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值(请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数---指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了)

2、WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status) 就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说, WIFEXITED返回0,这个值就毫无意义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值