一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
Test1
for(int i = 0; i<2; i++)
{
if(fork() == 0)
printf("A\n");
else
printf("B\n");
}
上述代码中,fork() 执行后会出现两个进程,子进程中的 fork() 返回值为 0,父进程中 fork() 返回值则是子进程的 pid
执行结果如下图
Test2
将上述代码稍微修改一下
for(int i = 0; i<2; i++)
{
if(fork() == 0)
printf("A");
else
printf("B");
}
该循环中打印没有字符 "\n",无法刷新缓冲区
每一次 fork() 会复制之前进程中缓冲区的字符
最后执行结果为
BBBAABAA
(取决于两个进程执行的顺序)
Test3
if(fork() && fork())
printf("A\n");
else
printf("B\n");
该 if 块中第一个 fork() 生成一个子进程,返回 0,所以第二个 fork() 不会执行
父进程返回 pid,执行第二个 fork(),再次产生一个子进程
所以最终 printf 调用了三次,最后执行结果为
A
B
B
Test4
#include
#include
// 测试栈空间的变量
void f0()
{
int tmp = 0;
int pid = fork();
if(pid == 0)
{
tmp++;
printf("son\n");
}
else if(pid > 0)
{
printf("parents\n");
}
else
{
return;
}
printf("%d\n",tmp);
}
int tmp1 = 5;
// 测试全局变量
void f1()
{
int pid = fork();
if(pid == 0)
{
tmp1++;
printf("son\n");
}
else if(pid > 0)
{
printf("parents\n");
}
else
{
return;
}
printf("%d\n",tmp1);
}
// 测试堆区变量
void f2()
{
int *tmp2 = (int*)malloc(sizeof(int));
*tmp2 = 0;
int pid = fork();
if(pid == 0)
{
(*tmp2)++;
printf("son\n");
}
else if(pid > 0)
{
printf("parents\n");
}
else
{
return;
}
printf("%d\n",*tmp2);
}
通过在 main 分别执行以上三个函数,输出中父进程与子进程打印的 tmp 值均不相同
可以发现,fork() 后生成新的子进程与父进程是相互独立的,拥有独立的 VMA
进程管理之fork函数
fork函数的定义 #include #include pid_t fork(void); fork函数在父进程中返回子进程的 ...
UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习
lienhua342014-10-07 在“进程控制三部曲”中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork ...
【Linux编程】进程标识符与fork函数
ID为0的进程一般是调度进程.常被称为交换进程(swapper),是内核中的系统进程. ID为1的进程叫做init进程,是一个普通用户进程,不属于内核,由内核调用. 一个现有进程能够调用fork函数创 ...
Linux进程管理知识整理
Linux进程管理知识整理 1.进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些? TASK_RUNNING(可运行状态) ...
Linux性能及调优指南(翻译)之Linux进程管理