fork 父进程?子进程 ?独立?关联?

说在前面:
本来想一次性看完之后再写总结记录的,但是发现第一次连续看完之后,很多细节当时明白了但是过后自己写代码的时候又没能注意起来,所以还是边看边总结吧

fork创建子进程

从man手册查看fork

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

   pid_t fork(void);

DESCRIPTION
fork() creates a new process by duplicating the calling process. The
new process is referred to as the child process. The calling process
is referred to as the parent process.

RETURN VALUE
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the
parent, no child process is created, and errno is set appropriately.

  1. 概要里面的头文件就略过了,记得加上,不然报错。

  2. fork() creates a new process by duplicating the calling process.
    就是说fork出来的文件是复制出来的,跟父进程一毛一样的,不点在于他们的pid不一样,通过判断pid的值来判断它是父进程还是子进程,从而进行操作。
    注意: 按照我通过课程学习的理解,这个复制的意思是整一篇代码,从开头的#include到最后的的return 0}结束这样复制,而不是简简单单的只是判断pid的那一段进行复制。结果结合代码看下图:我用的是atexit()在最后执行函数,可以看到是执行了两次的, 可以这样说,因为fork之后,这一份代码需要被父进程执行一次,被子进程执行一次,所以有两次atexit的结果。

  3. 看return value
    对照图看
    fork之后会有两个返回值,返回值=0的话证明是子进程,返回值>0的话证明是父进程,父进程的返回值就是子进程的pid。
    在子进程里面用getpid得到的pid才试自己的pid,与父进程的返回值一致
    在子进程里面用getppid得到的是父进程的pid,与父进程里面getpid一致

  4. 看图2圈起来的
    为什么子进程的pid和父进程的pid不一样?
    对比图1图2来看,图2是父进程先执行然后再执行子进程,这时候父进程先执行完之后就被释放掉了,所以子进程跟它挂不上了,系统就会把它挂给一个用户进程,pid是1071
    图1的话是子进程先执行再执行父进程,所以不存在这个情况。
    那怎么确定谁先执行,我也不知道,如果不想出现这样的情况的话可以在父进程里面加一个sleep(),这样就能保证在这段sleep的阻塞时间下你的子进程能够先执行完,不会变成孤儿被系统收养。

  5. 注意: 父子进程都是独立的(但是不能说完全独立,总有点关联),所以不要纠结在终端里面打印的测试信息谁先谁后的问题,反正都有就行了

  6. 在代码里面还加上了open read write 这些都能用,只是注释了方便测试上述的问题。

结果图

图1
在这里插入图片描述
图2
在这里插入图片描述

代码

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

void prt(void)
{
	
	printf("会调用两次执行两次\n");
}


 
int main(int argc,char **argv)
{
	if(argc != 2)
	{
		printf("usage: ./a.out filename\n");
		exit(-1);
	}
	else
	{
		pid_t idflag = -1;
		idflag = fork();
		
		if (idflag > 0)
		{
			printf("父进程\n");
			/*
			int fd = -1;
			fd = open(argv[1],O_RDWR|O_APPEND);
			if (fd < 0)
			{
				perror("open");
				return -1;
			}
			int wt = -1;
			char buf[4] = "abcd";
			wt = write(fd,buf,sizeof(buf));
			if (-1 == wt)
			{
				perror("write");
				return -1;
			}
			printf("idflag = %d\n",idflag);
			close(fd);
			*/
			printf("the idflag of parent means its child pid = %d\n",idflag);
			printf("my id is  = %d\n",getpid());
			
		}
		else if (0 == idflag)
		{
			printf("子进程\n");
			/*
			int fd = -1;
			fd = open(argv[1],O_RDWR|O_APPEND);
			lseek(fd,0,SEEK_SET);
			
			int rd = -1;
			char buf2[300] = {0};
			rd = read(fd,buf2,sizeof(buf2));
			if (-1 == rd)
			{
				perror("read");
				return -1;
			}
			printf("\n the bytes that read is %d\n",rd);
			printf("\n the data that written is %s\n\n",buf2);
			close(fd);
			*/
			printf("child idflag = %d\n",idflag);
			printf("child pid is  = %d\n",getpid());
			printf("parent pid is  = %d\n",getppid());
		}
		else if (-1 == idflag)
		{
			perror("fork");
			return -1;
		}
		
	}
	atexit(prt);
	return 0;
}
发布了38 篇原创文章 · 获赞 1 · 访问量 1039

猜你喜欢

转载自blog.csdn.net/qq_40897531/article/details/103833398
今日推荐