URL
type
status
date
slug
summary
tags
category
icon
password
题目:您的目标是使用和来设置管道。第一个进程将数字2到35输入管道。对于每个素数,您将安排创建一个进程,该进程通过一个管道从其左邻居读取数据,并通过另一个管道向其右邻居写入数据。由于xv6的文件描述符和进程数量有限,因此第一个进程可以在35处停止。
c语言忘的差不多了,敲得生疏,题目对我来说也确实有点难,倒腾了一下午终于实现了。
看了b站几个大佬的实现方式,都是用数组一次性将35个数字传给下一个进程,这样一个进程接着一个进程的传数据,实际上是线性的。而书中描述的似乎是一种并发的流水线操作,数字一个一个进入进程,一个一个流出进程到下一个进程,所有进程被数据的水流串起来,而每个进程都在同时处理这条水流,就像工厂的流水线一样。
最后我想到每个进程中用一个循环来一个个的获取上一个管道的数据,循环中套循环处理后再一个一个的发送给下一个进程(感觉和用数组打包传差不太多😂)
经过多次改进,终于可以做到最大化发挥xv6的性能,将xv6操作系统的64个线程全部跑满,经测试可以筛选出270以内的所有素数。
踩过的坑:
- 整个结构的设计,每个进程都循环的从前一个管道fd读取数据,经判断后发送给下一个管道p_next,一个数一个数的读取,整体来看,每个线程都同时在不停的读取输出。因此要先fork了再在父进程循环的读写。
- 要利用wait,等待子进程关闭再关闭父进程,不然父进程提前关闭会导致程序无法结束。
- 前一个进程发送完所有数据即时释放这个进程上连接的所有管道,一方面后面的进程不会阻塞,一方面xv6的文件标识符有限,前面的释放了给后面的用。
对管道的理解,两个进程用一个管道连接的话,会有四个头。和父进程连接一个读一个写,子进程也是如此。各自删除一个读一个写就成一个单向的管道。管道里若没有数据就会堵着不动,这时要么传输数据,要么把写头关了。如下图:
