我正在尝试学习UNIX编程并遇到有关taxAmount
的问题,我无法解释下面两个程序的输出。
我理解fork()
创建了一个当前正在运行的进程的相同进程,但是它从哪里开始?例如,如果我有以下这两个程序,那么输出是什么以及它是如何工作的?
fork()
以上程序和下面的程序有什么不同 尊重子流程执行:
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main (int argc, char **argv)
{
int retval;
printf ("This is most definitely the parent process\n");
// now here fork will create a child process
// i need to know from which line child process starts execution
retval = fork ();
printf ("Which process printed this?\n");
return (0);
}
我认为他们都应该打印出来:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main (int argc, char **argv)
{
int retval;
printf ("This is most definitely the parent process\n");
fflush (stdout);
// how does fflush change the output of above program and why ?
// even though no string operations are being used
retval = fork ();
printf ("Which process printed this?\n");
return (0);
}
但第一个是印刷:
This is most definitely the parent process
Which process printed this?
Which process printed this?
答案 0 :(得分:3)
我知道fork()创建了一个与当前相同的进程 运行过程,但它从哪里开始?
如果fork(2)
成功(即不返回-1
),则会从调用fork(2)
的行开始。 fork(2)
返回两次:它在子项中返回0,在父项中返回正数C
,其中C
是新生儿的进程ID。
你看到的原因这绝对是父进程两次与stdio的缓冲有关。 Stdio缓冲用户空间缓冲区中的输出,这些缓冲区仅在发生某些条件时刷新(例如,缓冲区变满)。缓冲模式决定了刷新缓冲区的时间和方式。
通常,如果将输出写入交互设备(如终端(或伪终端)),则stdio是行缓冲,这意味着在找到换行符时刷新缓冲区或{ {1}}被调用。
OTOH,如果输出被重定向到文件或其他非交互设备(例如,输出被重定向到管道),则stdio 完全缓冲,这意味着只刷新缓冲区当它们变满或被叫fflush(3)
时。
因此,如果没有fflush(3)
,在终端设备中执行代码将打印出来:
fflush(3)
预期。但是,如果你通过This is most definitely the parent process
Which process printed this?
Which process printed this?
管道,你会看到这个(或其他一些变体,取决于执行顺序):
cat(1)
这是因为重定向到管道时输出完全缓冲。字符串This is most definitely the parent process
Which process printed this?
This is most definitely the parent process
Which process printed this?
不足以填充和刷新缓冲区,因此当父分叉时,子代(获取父代的内存空间的副本)将获得输出缓冲区的副本,该缓冲区已包含字符串This is most definitely the parent process
。因此,两个进程最终都会打印该字符串。
如果你总是在分叉之前调用This is most definitely the parent process
,那么这不会发生,因为当父母的内存空间被复制到孩子时,缓冲区是空的。
答案 1 :(得分:0)
执行将在fork调用(或之后)继续执行。您可以使用返回值来检查您是父进程还是子进程:
返回值
成功时,子进程的PID将在父进程中返回,并返回0 在孩子身上失败时,在父项中返回-1,不创建子进程, 和errno设置得恰当。
(来源:man fork
)
例如,如果您有以下程序:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) {
printf("Foo.\n");
int retval = fork();
printf("Bar from %s (%d).\n", (retval == 0) ? "child" : "parent", retval);
return 0;
}
输出类似于:
Foo.
Bar from parent (18464).
Bar from child (0).
...假设输出是行缓冲的。
答案 2 :(得分:0)
在致电for (int i = 0; i < random.Length; i++)
{
if (guessBool [i])
guessChar += random[i] + " ";
else
guessChar += "_ ";
}
GetComponent<TextMesh> ().text = guessChar;
时,有三种可能的退货条件。
请阅读fork()
三个返回条件是
fork()
代码必须是这样的:
-1 -- the fork() failed
0 -- the child is executing
some positive number -- the pid of the child, the parent is executing