fork创建子进程

原理

image
image
返回的值:父进程返回子进程PID,子进程返回0(类似成功创建的意思)

fork基本代码

/*************************************************************************
	> File Name: fork_test.c
	> Author: shaozheming
	> Mail: 957510530@qq.com
	> Created Time: 2022年02月26日 星期六 15时01分13秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc, char* argv[])
{
	printf("run--1--\r\n");
	printf("run--2--\r\n");
	printf("run--3--\r\n");
	printf("run--4--\r\n");
	printf("run--5--\r\n");

	pid_t pid = fork();

	if(pid < 0){
		perror("fork error!\r\n");
		exit(1);
	} else if(pid == 0) {
		printf("child pid is created\r\n");
	} else {
		printf("father pid is %d\r\n", pid);
	}

	printf("------end------\r\n");
    return 0;
}

image

getpid和getppid

/*************************************************************************
	> File Name: fork_test.c
	> Author: shaozheming
	> Mail: 957510530@qq.com
	> Created Time: 2022年02月26日 星期六 15时01分13秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc, char* argv[])
{
	printf("run--1--\r\n");
	printf("run--2--\r\n");
	printf("run--3--\r\n");
	printf("run--4--\r\n");
	printf("run--5--\r\n");

	pid_t pid = fork();

	if(pid < 0){
		perror("fork error!\r\n");
		exit(1);
	} else if(pid == 0) {
		printf("child pid is %d, parent pid is %d\r\n", getpid(), getppid());
	} else if(pid > 0){
		pid_t temp = getpid();
	//if(temp == pid)
			printf("father pid is %d, parent pid is %d\r\n", temp, getppid());
	}

	printf("------end------\r\n");
    return 0;
}

image

ps aux | grep xxx

  • ps a 显示现行终端机下的所有程序,包括其他用户的程序。
  • ps -A 显示所有程序。
  • ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。
  • ps -e 此参数的效果和指定"A"参数相同。
  • ps e 列出程序时,显示每个程序所使用的环境变量。
  • ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
  • ps -H 显示树状结构,表示程序间的相互关系。
  • ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
  • ps s 采用程序信号的格式显示程序状况。
  • ps S 列出程序时,包括已中断的子程序资料。
  • ps -t  指定终端机编号,并列出属于该终端机的程序的状况。
  • ps u  以用户为主的格式来显示程序状况。
  • ps x  显示所有程序,不以终端机来区分。

ps是显示当前状态处于running的进程,grep表示在这些里搜索,而ps aux是显示所有进程和其状态。
$ ps aux | grep amoeba
查到amoeba的进程
$ kill -s 9 pid
杀死进程, 因此可知3386就是bash

循环创建多个子进程

/*************************************************************************
  > File Name: fork_test.c
  > Author: shaozheming
  > Mail: 957510530@qq.com
  > Created Time: 2022年02月26日 星期六 15时01分13秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc, char* argv[])
{
	int i;
	for(i = 0; i < 5; ++i){
		if(fork() == 0) {
			//表示是子进程
			break;
		}
	}
	if(i == 5){
		printf("I'm father!,PID is %d\r\n", getpid());
		exit(1);
	}

	printf("child %d PID is %d, parent PID is %d\r\n", i+1, getpid(), getppid());
	return 0;
}

image
也有可能出现以下现象
image
此时有可能出现这种情况,就是父进程执行完毕后,有一些子进程还没有创建完毕(和CPU调度有关),bash出来之后才会打印子进程,此时的子进程叫孤儿进程

父子进程共享

image
注意是相同不是共享
代码如下图所示:
image
var是全局变量,写的时候两个var的值不一样,当读的时候,在子进程上var的值还是100,(注释掉修改var的操作)
image
在这里看到父子进程并不是肯定共享全局变量,因为读时共享,写时复制,共享文件描述符和mmap映射区
总结一下:
image

gdb调试父子进程

image

posted @ 2022-02-26 16:53  蘑菇王国大聪明  阅读(93)  评论(0编辑  收藏  举报