【进程】(一)进程创建fork()与vfork()

一、例程说明

1、调用fork()创建进程,分析创建进程的过程和fork()的返回值变化
2、调用vfork()创建进程,比较与fork函数的区别
2、验证fork()与vfork(),父进程和子进程所占用的存储空间是否共享

二、fork()例程代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
int g =0;
int main(int argc, char*argv[])
{
        pid_t ret_pid; //定义pid返回值
        int a =0;      //定义局部变量
        if((ret_pid = fork()) < 0) //调用fork函数创建子进程
        {
                perror("fork failed.why:");
        }
        else if(ret_pid > 0)
        {
                printf("this is farther progress(farther current pid = %d ), ret_pid = %d\r\n", getpid(),ret_pid);
                a+=10;   //父进程改变局部变量
                g += 10; //父进程改变全局变量
        }
        else if(ret_pid == 0)
        {
                printf("this is childr progress(child current pid = %d ), ret_pid = %d\r\n", getpid(),ret_pid);
                a+=20;  //子进程改变局局变量
                g+=20;  //子进程改变全局变量
        }
        printf("a = %d\r\n", a);        
        printf("g = %d\r\n", g);
		exit(0); //等价于return(0),exit函数对所有打开流调用fclose函数,清洗缓冲,终止进程
}

例程执行结果与分析

this is farther progress(farther current pid = 28942 ), ret_pid = 28943
a = 10
g = 10
this is childr progress(child current pid = 28943 ), ret_pid = 0
a = 20
g = 20

1)根据结果中父进程和子进程的全局与局部变量的值,可知父进程与子进程对全局、局部变量的改变互不影响,即子进程只是父进程数据空间、堆栈空间的副本,并不共享这些存储空间,仅共享正文段。
2)根据结果中的fork函数返回值ret_pid可知,在父进程中,fork返回值ret_pid为28943(非负整数)作为了子进程的ID;在子进程中,fork返回值ret_pid返回值为0。即调用fork函数,一次执行,两次返回。
3)经过多次执行,父进程和子进程谁先执行并不确定(可用sleep()函数来控制执行的先后。

三、vfork()例程代码

#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
int global_val = 0;
int main(void)
{
        int a = 0;
        pid_t pid;
        if((pid = vfork()) < 0)
        {
                perror("vfork failed,why:");
        }       
        else if(pid > 0)
        {
                printf("this is farther progress(farther pid = %d ), pid =  %d\r\n", getpid(), pid);
                global_val+=10;
                a+=10;
        }
        else if(pid == 0)
        {
                printf("this is child progress(child pid = %d), pid = %d\r\n", getpid(),pid);
                global_val+=20;
                a+=20;
        //      _exit(0);//如果子进程调用_exit,即终止了子进程,之后将不再执行后面的语句
        }
        printf("global_val = %d\r\n", global_val);
        printf("a = %d\r\n", a);
        exit(0);
}

例程执行结果

this is child progress(child pid = 31252), ret_pid = 0
global_val = 20
a = 20
this is farther progress(farther pid = 31251 ), ret_pid =  31252
global_val = 30
a = 30

1)根据结果中父进程和子进程的全局与局部变量的值,可知父进程与子进程对全局、局部变量的改变是相互影响的,即父进程与子进程共享地址空间
2)根据结果中的vfork()函数返回值ret_pid可知,在父进程中,fork()返回值ret_pid为28943(非负整数)作为了子进程的ID;在子进程中,fork()返回值ret_pid返回值为0。即调用fork()函数,一次执行,两次返回这与fork()函数是相同的)。
3)经过多次执行,由vfork()创建的子进程,父进程总是会等待子进程执行完毕(内核会将父进程处于休眠状态),才可能调度运行。
4)在子进程中如果未调用exit或者exec,父进程可能将会处于阻塞的状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值