要打印的文本正在命令行上打印,而不是在终端上使用 fork 时打印 space
The text to be printed is being printed on the command line rather than print space while using fork on terminal
所以在 ubuntu 终端中,当我 运行 一段简单的代码使用 fork 从子进程和父进程打印时,终端打印子进程的打印语句命令行而不是之前。我想知道是否有解决办法。
我对使用系统调用有点陌生,所以我真的没有尝试很多东西
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]){
printf("(%d) Start\n", (int)getpid());
int rc = fork();
if(rc < 0 ){
fprintf(stderr, "Error\n");
exit(1);
}
else if(rc == 0){
printf("(%d) Hello from the child, I got %d. My parent is %d\n", (int)getpid(), (int)rc, (int)getppid());
}
else{
printf("(%d) Hello from the parent, I got %d. My parent is %d\n", (int)getpid(), (int)rc, (int)getppid());
}
return 0;
}
我希望打印的语句都在两个命令行之间,但最后一行一直打印在命令行上:
但是waiting其实并不是一个很好用的同步工具。例如,您应该在父子进程之间打开一个管道,并通过该管道发送来自子进程的数据,或者使用其他同步工具,例如信号量、消息队列甚至 TCP/IP 套接字让两个进程相互通信,当您关心消息的顺序时。
参见 pipe(2)、socketpair(2)、socket(7) 和 svipc(7)。
掌握POSIX IPC 和过程通信是成为真正的过程控制大师的途径。
还要检查golang(channels)中使用通信串行进程(CSP)进行同步和通信的方式。请参阅 https://blog.golang.org/go-concurrency-patterns-timing-out-and 和所有其他 go-concurrency 博客和讲座!
这是竞态条件的经典示例。在 fork
调用之后,根据定义,您有两个独立的进程和两个控制线程。理论上,它们 运行ning 是并行的。 (在多处理器或多核机器上,它们可能 实际上 运行 并行。)
在 parent 中,我们发生了这些事情:
- 打印"Hello from the parent"
- 退出返回呼叫者
- 调用方打印下一个提示
在child,我们发生了这些事情
- 打印"Hello from the child"
- 退出
parent 进程(在此上下文中)是调用 shell 的 child。因此 shell 等待的是 parent 进程;它是 parent 进程(第 2 步)的退出,将触发打印下一个 shell 提示(第 3 步)。说 child 退出后会发生什么更复杂,但由于它不会导致打印任何内容(或我们可以看到的任何内容),所以它最终并不重要。
但是由于我们有两个控制线程和一个竞争条件,我们可以根据不同打印步骤的交错方式看到不同的结果:
thread of control #1 thread of control #2
------ -- ------- -- ------ -- ------- --
1. Hello from the parent
4. Hello from the child
3. next shell prompt
或
1. Hello from the parent
3. next shell prompt
4. Hello from the child
或者也许
4. Hello from the child
1. Hello from the parent
3. next shell prompt
但是你得到的这些结果中的哪一个实际上取决于任何事情。 (这是竞争条件的本质。)所以我对你教授的计算机表现出不同的行为并不感到惊讶。 (一方面,虽然MacOS确实非常Unix-like,但它是基于下面的一个Mach microkernel,改变了一些东西。)
如果您仍然不满意,这里有一个 -- 可能 far-fetched -- 类比。
这听起来像是您认为在程序——整个程序——完成之前不应该得到另一个 shell 提示。听起来你认为 "the program" 应该不可能在它完成后打印任何东西,也就是说,在你看到下一个 shell 提示它已经完成之后。
假设您 运行 一个治疗中心。假设您有一个 "screaming room",人们可以在那里大声尖叫,以宣泄他们的挫败感。因此,当您从那个房间听到尖叫声时,您知道这是来自您的一位患者,但如果那里没有患者,您就不会期望听到任何尖叫声。
所以有一天,一个压力很大的女人进来了,你把她带到了尖叫的房间,你听到了相当多的尖叫声,但过了一会儿她又回来了,你移动了那个小标志在从 "occupied" 回到 "unoccupied" 的门上。但是,令你惊讶的是,你听到门后传来另一声尖叫(更像是哭泣)...
哦,我有没有提到那个女人一开始压力很大的原因是她怀孕很重,快要生了?
所以在 ubuntu 终端中,当我 运行 一段简单的代码使用 fork 从子进程和父进程打印时,终端打印子进程的打印语句命令行而不是之前。我想知道是否有解决办法。
我对使用系统调用有点陌生,所以我真的没有尝试很多东西
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]){
printf("(%d) Start\n", (int)getpid());
int rc = fork();
if(rc < 0 ){
fprintf(stderr, "Error\n");
exit(1);
}
else if(rc == 0){
printf("(%d) Hello from the child, I got %d. My parent is %d\n", (int)getpid(), (int)rc, (int)getppid());
}
else{
printf("(%d) Hello from the parent, I got %d. My parent is %d\n", (int)getpid(), (int)rc, (int)getppid());
}
return 0;
}
我希望打印的语句都在两个命令行之间,但最后一行一直打印在命令行上:
但是waiting其实并不是一个很好用的同步工具。例如,您应该在父子进程之间打开一个管道,并通过该管道发送来自子进程的数据,或者使用其他同步工具,例如信号量、消息队列甚至 TCP/IP 套接字让两个进程相互通信,当您关心消息的顺序时。
参见 pipe(2)、socketpair(2)、socket(7) 和 svipc(7)。
掌握POSIX IPC 和过程通信是成为真正的过程控制大师的途径。
还要检查golang(channels)中使用通信串行进程(CSP)进行同步和通信的方式。请参阅 https://blog.golang.org/go-concurrency-patterns-timing-out-and 和所有其他 go-concurrency 博客和讲座!
这是竞态条件的经典示例。在 fork
调用之后,根据定义,您有两个独立的进程和两个控制线程。理论上,它们 运行ning 是并行的。 (在多处理器或多核机器上,它们可能 实际上 运行 并行。)
在 parent 中,我们发生了这些事情:
- 打印"Hello from the parent"
- 退出返回呼叫者
- 调用方打印下一个提示
在child,我们发生了这些事情
- 打印"Hello from the child"
- 退出
parent 进程(在此上下文中)是调用 shell 的 child。因此 shell 等待的是 parent 进程;它是 parent 进程(第 2 步)的退出,将触发打印下一个 shell 提示(第 3 步)。说 child 退出后会发生什么更复杂,但由于它不会导致打印任何内容(或我们可以看到的任何内容),所以它最终并不重要。
但是由于我们有两个控制线程和一个竞争条件,我们可以根据不同打印步骤的交错方式看到不同的结果:
thread of control #1 thread of control #2
------ -- ------- -- ------ -- ------- --
1. Hello from the parent
4. Hello from the child
3. next shell prompt
或
1. Hello from the parent
3. next shell prompt
4. Hello from the child
或者也许
4. Hello from the child
1. Hello from the parent
3. next shell prompt
但是你得到的这些结果中的哪一个实际上取决于任何事情。 (这是竞争条件的本质。)所以我对你教授的计算机表现出不同的行为并不感到惊讶。 (一方面,虽然MacOS确实非常Unix-like,但它是基于下面的一个Mach microkernel,改变了一些东西。)
如果您仍然不满意,这里有一个 -- 可能 far-fetched -- 类比。
这听起来像是您认为在程序——整个程序——完成之前不应该得到另一个 shell 提示。听起来你认为 "the program" 应该不可能在它完成后打印任何东西,也就是说,在你看到下一个 shell 提示它已经完成之后。
假设您 运行 一个治疗中心。假设您有一个 "screaming room",人们可以在那里大声尖叫,以宣泄他们的挫败感。因此,当您从那个房间听到尖叫声时,您知道这是来自您的一位患者,但如果那里没有患者,您就不会期望听到任何尖叫声。
所以有一天,一个压力很大的女人进来了,你把她带到了尖叫的房间,你听到了相当多的尖叫声,但过了一会儿她又回来了,你移动了那个小标志在从 "occupied" 回到 "unoccupied" 的门上。但是,令你惊讶的是,你听到门后传来另一声尖叫(更像是哭泣)...
哦,我有没有提到那个女人一开始压力很大的原因是她怀孕很重,快要生了?