linux系统编程之进程创建实战,fork与vfork创建进程的区别

1.首先我们先来了解一下fork创建进程:
(1)使用fork函数创建一个进程,pid_t fork(void),
fork函数调用成功的话,返回两次
返回值为0, 代表当前进程是子进程。
返回值为非负数,代表当前进程是父进程。
调用失败的话,返回-1。

重要提示:调用fork函数时,父进程的返回值就是子进程的进程ID,而子进程的返回值是0;

(2)fork函数创建一个子进程的一般目的
在这里插入图片描述
(3)fork编程实战
在这里插入图片描述
(4)直接上代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    
    
        pid_t pid1;
        pid_t pid2;
        pid_t retpid;

        pid1 = getpid();
        printf("before fork the pid1:%d\n",pid1);

        retpid = fork();

        pid2 = getpid();
        printf("after the fork the pid2:%d\n",pid2);

        if(pid1 == pid2)
        {
    
    
                printf("this is father process,the pid is:%d,the retpid is:%d\n",pid1,retpid);
        }
        else if(pid1 != pid2)
        {
    
    
                printf("this is child process,the pid is:%d,the retpid   is:%d\n",pid2,retpid);
        }

        return 0;
}

结果:
在这里插入图片描述
从结果中可以看出,父子进程是交换执行的。

(5)fork函数创建的子进程与父进程的内存关系
在这里插入图片描述
(6)证明fork函数创建的子进程跟父进程并不是共用存储空间的
直接上代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    
    
        pid_t pid;
        int data = 0;

        pid = fork();

        if(pid > 0)
        {
    
    
                while(1){
    
    
                        data++;
                        printf("data = %d\n",data);
                        printf("this is father process\n");
                        sleep(3);
                }
        }
        else if(pid == 0)
        {
    
    
                while(1){
    
    
                        data++;
                        printf("data = %d\n",data);
                        printf("this is child process\n");
                        sleep(3);
                }
        }
        
		return 0;	
}

结果:
在这里插入图片描述
从以上结果我们看到在父进程跟子进程里的data值是不叠加的,而是各自加各自的,所以我们可以知道fork方式创建的子进程是不跟父进程共用存储空间的。

2.介绍完fork创建进程,接下来我们来介绍一下用vfork函数来创建进程;
(1)使用vfork创建一个进程:pid_t vfork(void);
(2)vfork()创建进程与fork()创建进程的区别;
区别一,vfork直接使用父进程的存储空间,不进行拷贝,(说白了就是与父进程共用一段内存空间)
区别二,vfork保证子进程先运行,当子进程调用exit()退出后,父进程才执行,而fork是父子进程交替 执行。
(3)vfork的返回值
vfork函数调用成功的话,返回两次
返回值为0, 代表当前进程是子进程。
返回值为非负数,代表当前进程是父进程。
调用失败的话,返回-1。
返回值其实是跟fork是一模一样的,只不过是父进程先让子进程先运行,子进程调用exit函数退出后再到父进程,父进程的返回值依然是子进程的ID号。

(4)闲话不多说,直接上的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    
    
        pid_t pid;
        int cnt = 0;

        pid = vfork();

        if(pid > 0)
        {
    
    
                while(1)
                {
    
    
                        printf("this is father process,the pid is :%d\n",pid);
                        sleep(3);
                        printf("cnt = %d\n",cnt);
                }
        }
        else if(pid == 0)
        {
    
    
                while(1)
                {
    
    
                        printf("this is child process,pid = %d\n",getpid());
                        sleep(3);
                        cnt++;
                        if(cnt > 3)
                        {
    
    
                              exit(0);
                        }
                }
        }
        return 0;
}

结果:
在这里插入图片描述
从结果中我们可以看出最主要的一点就是父进程中的cnt的值是接着子进程的累加上来的,这就说明了vfork方式创建的子进程是跟父进程共用一段存储空间的,而且父进程的返回值依然是子进程的ID号(虽然是子进程先运行)。

学习笔记,仅供参考。

猜你喜欢

转载自blog.csdn.net/weixin_51976284/article/details/124365573