该
vfork()函数具有相同的效果fork(2),除非在成功调用[...]exec(3)函数族之一之前,如果进程调用任何其他函数,则行为未定义.
这表明exec*()之后调用任何函数vfork()是可以接受的.但是,稍后在手册页中明确说明:
特别是,程序员不能依赖父母保持阻止,直到孩子打电话
execve(2)[...].
execve(2)在手册页中重复使用,它的用法表明它是唯一exec可以接受的类型函数vfork().
那么为什么execve被挑选出来,我可以安全地调用其他exec类型的函数(比如execlp)?
在子进程中,有什么方法可以确定它是作为具有覆盖内存的 fork 还是作为具有共享内存的 vfork 启动的?
基本上,我们的日志引擎需要在 vfork 中更加小心(而不是记录某些类别的活动)。在 fork 中,它需要以 vfork 中没有的方式与父进程合作。我们知道如何做这两件事,但不知道如何决定。
我知道我可能会拦截 fork/vfork/clone 调用,并将 fork/vfork/mapping 状态存储为一个标志,但是如果孩子可以通过 API 调用来确定它自己的状态,这会让生活变得更简单。
额外标记:理想情况下,我还需要在库中选择任何已经完成 fork 或 vfork 的地方,然后再调用我们的代码。那怎么会发生呢?我们至少有一个库提供了类似 popen 的 API,其中在 exec 之前从 fork 子级调用客户端回调。显然,该回调的效用在 vfork 中受到显着限制。
子进程和父进程执行是并行的,首先取决于OS调度.但是,总是在父母之前开始做孩子可以做些什么呢?
这是我的问题的伪代码,
int start_test()
{
pid_t pid;
pid = fork();
if(pid == 0) {
execv("XXX", XXX);
} else if(pid > 0) {
pid = fork();
if(pid == 0) {
execv("XXX", XXX);
} else {
// Do something
}
}
return 0;
}
int main()
{
start_test();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想首先执行execv,然后再次创建新进程.每个execv应该按顺序.
以下代码永远不会结束.这是为什么?
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#define SIZE 5
int nums[SIZE] = {0, 1, 2, 3, 4};
int main()
{
int i;
pid_t pid;
pid = vfork();
if(pid == 0){ /* Child process */
for(i = 0; i < SIZE; i++){
nums[i] *= -i;
printf(”CHILD: %d “, nums[i]); /* LINE X */
}
}
else if (pid > 0){ /* Parent process */
wait(NULL);
for(i = 0; i < SIZE; i++)
printf(”PARENT: %d “, nums[i]); /* LINE Y */ …Run Code Online (Sandbox Code Playgroud) 我正在做一些自我学习的C练习,并遇到了以下问题:
第一部分:
int main(int argc, char **argv) {
int a = 5, b = 8;
int v;
v = fork();
if(v == 0) {
// 10
a = a + 5;
// 10
b = b + 2;
exit(0);
}
// Parent code
wait(NULL);
printf("Value of v is %d.\n", v); // line a
printf("Sum is %d.\n", a + b); // line b
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
b部分:
int main(int argc, char **argv) {
int a = 5, b = 8;
int v; …Run Code Online (Sandbox Code Playgroud) vfork可以在父进程中更改变量,但为什么不能增加堆栈呢?
void f1()
{
vfork();
}
Run Code Online (Sandbox Code Playgroud)
f2()导致崩溃.
void f2()
{
char buf[100];
}
int main()
{
f1();
f2();
_exit(0);
}
Run Code Online (Sandbox Code Playgroud)
如果我将vfork()更改为fork(),则不会发生崩溃.