Linux高并发服务器开发 第十五天(fork函数)
目录
1.fork 函数
1.1创建子进程
1.2getpid 函数
1.3getppid 函数
1.4getgid函数
1.5循环创建 n 个子进程
1.6fork后父子进程异同
1.6.1读时共享,写时复制
1.6.2fork后父子进程共享
1.6.3gdb调试父子进程
1.fork 函数
pid_t fork(void);
成功:// fork之后,会产生一个子进程。 父、子进程各自对fork函数做返回。
父进程:返回 子进程id
子进程:返回 0
失败: // 不产生子进程。
-1 errno注意: pid_t是一个short类型的变量,实际表示的是内核中的进程表的索引
- fork 之后,父、子进程,共同争夺cpu ,执行先后顺序随机,如下
1.1创建子进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
printf("=============before fork=============\n");
pid_t pid = fork();
if (pid == -1)
sys_err("fork error");
if (pid == 0)
{ // 子进程
printf("Iam child, 我的id = %d\n", getpid());
} else if (pid > 0)
{ // 父进程
printf("I am parent, 我儿子的id = %d, 我的id= %d\n", pid, getpid());
}
printf("=============after fork=============\n");
return 0;
}
1.2getpid 函数
pid_t getpid(void);
获取当前进程ID
1.3getppid 函数
pid_t getppid(void);
获取当前进程的父进程ID
- **ps aux | grep 关键字**。 —— 搜索系统中包含关键字的进程。
- ./a.out 进程的父进程 bash
- 系统调用函数、库函数区别:
- 1. 访问内核数据结构。 2. 访问硬件资源。
- 系统调用: 以上两者二占其一。
- 库函数:以上两者均不占。
1.4getgid函数
pid_t getgid(void);
pid_t getegid(void);
//获取当前进程使用用户组ID
//获取当前进程有效用户组ID
1.5循环创建 n 个子进程
- 为了避免 子进程也fork产生 “孙进程”。 需要每次fork 后,将子进程 结束运行,不参与下一次fork。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < 5; i++)
{
if (fork() == 0)
break; // 循环期间,子进程不参与循环.
}
if (5 == i)
{ // 循环从 表达式 2 结束. --- 父进程
sleep(5);
printf("I'm parent \n");
} else {
sleep(i);
printf("I'm %dth child\n", i+1);
}
return 0;
}
1.6fork后父子进程异同
“刚刚” fork 后:
父子相同:
- 全局变量、.data、.text、栈、堆、环境变量、用户ID、进程工作目录、宿主目录、信号处理方式...
父子不同:
- 进程ID、fork返回值、进程运行时间、父进程ID、闹钟(定时器)、未决信号集。
1.6.1读时共享,写时复制
- fork后,对于父进程的用户空间的数据,系统采用 读时共享,写时复制 原则。
- 重点常用:全局变量。
1.6.2fork后父子进程共享
1. 文件描述符(对应 打开的文件结构体)
2. mmap 创建的映射区。
1.6.3gdb调试父子进程
- 在 fork 函数调用之前:
- 跟踪父进程执行逻辑:set follow-fork-mode parent(默认)
- 跟踪子进程执行逻辑:set follow-fork-mode child