fork创建子进程
原理
返回的值:父进程返回子进程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;
}
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;
}
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;
}
也有可能出现以下现象
此时有可能出现这种情况,就是父进程执行完毕后,有一些子进程还没有创建完毕(和CPU调度有关),bash出来之后才会打印子进程,此时的子进程叫孤儿进程
父子进程共享
注意是相同不是共享
代码如下图所示:
var是全局变量,写的时候两个var的值不一样,当读的时候,在子进程上var的值还是100,(注释掉修改var的操作)
在这里看到父子进程并不是肯定共享全局变量,因为读时共享,写时复制,共享文件描述符和mmap映射区
总结一下:
gdb调试父子进程
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈