在fork() 之后,您有两个进程,我将它们命名为A 和B,它们执行这些操作:
1) read(fd, buf, 1);
2) read(fd, buf+1, 1);
3) printf("%c%c", buf[0], buf[1]);
你可以写出所有可能的组合。一个示例组合是:
-
A 执行语句1,从而从文件中读取1 并增加文件中的光标位置
-
A 执行语句2,从而从文件中读取2 并增加文件中的光标位置
-
A 激发声明3,即。打印12
-
B 从文件中读取3
-
B 从文件中读取4
-
B 打印 34。
等等。这些语句可以按任何顺序执行,因此首先处理 B 并先读取,然后处理 A 并先读取,然后处理 B 等等。
我们可以观察到进程总是会从文件中读取越来越多的数字。有以下可能性:
- a) 第一个进程将读取
12,然后第二个进程将读取34。
- b) 第一个进程将读取
1,然后第二个将读取2,然后第一个将读取3,然后第二个将读取4
- c) 第一个进程可以读取
1,然后第二个将读取23,然后第一个将读取4
“第一个进程”和“第二个进程”不是进程A或B,没关系,是第一个进程得到cpu时间。两个进程中的printfs 也可以按任何顺序运行。所以我们现在可以得到所有可能的输出:
- a)1)
1234
- a)2)
3412
- b)1)
1324
- b)2)
2413
- c)1)
1423
- c)2)
2314
我假设进程的输出是完全缓冲的,所以进程要么写入printf("%c%c", buf[0], buf[1]); 的完整输出,要么不写入。如果输出没有缓冲,那么例如一个进程可能会打印printf("%c", buf[0]),然后第二个进程可能会打印它的buf[0],然后第一个进程会打印它的buf[1],然后是第二个的buf[1]。然后你会得到更多的组合,因为基本上语句printf("%c%c", buf[0], buf[1])变成了两个语句printf("%c", buf[0])和printf("%c", buf[1]),它们在每个进程中一个接一个地执行,但是两个进程可以以任何顺序运行它们。
输出1423是可能的,如果一个进程从文件中读取1,然后另一个进程从文件中读取23,那么其中一个进程读取4并打印14 ,然后其他打印出23。