将每线程流连接到单独进程的最佳方法

时间:2013-06-06 10:07:35

标签: multithreading bash io process-substitution

我有一个使用线程并行化的计算密集型进程X. 跨多个CPU。每个线程产生流输出和每个流 应该分别连接到它自己的第二个进程Y的实例(那里 将有多个进程Y运行,因为有线程)。 X和Y分别写入和读取二进制格式,以便吞吐量非常好。 我想尽量减少任何I / O开销,并且正在寻找最好的方法。 目前我的设置看起来像这样(只用两个线程说明,但通常我会有八个以上):

exec 4> >( programY > out.4 )
exec 5> >( programY > out.5 )

programX-that-writes-to-fd-4-and-5

exec 4>&-
exec 5>&-

一个问题是bash手册指出:“使用大于9的文件描述符的重定向应该小心使用,因为它们可能与shell在内部使用的文件描述符冲突。”这不是很清楚。另一个问题是我没有找到建立终止的好方法:目前我使用“lsof -c programY”,但这感觉就像一个黑客。是否有更好或改进的解决方案?这里的'给定'是X是多线程的并且是计算密集型的,Y是单线程的并且是计算密集型的,并且X的每个线程必须连接到Y的实例。

1 个答案:

答案 0 :(得分:1)

我可能会设计程序X,以便可以告诉它要启动多少个子进程并为其创建一个模板(实际上是一个printf()格式字符串)来创建这些进程: / p>

alt-X -n 100 -f "Y > out.%d"

并让它处理文件描述符等。

但是,如果失败,您可以使用shell脚本,例如:

for ((i = 4; i < 104; i++))
do eval "exec $i> >(programY > out.$i)"
done

programX -d 4 -n 100 &   # Tell programX to write on file descriptors 4 to 103.

# Optionally
for ((i = 4; i < 104; i++))
do eval "exec $i>&-"
done

wait

wait命令在继续之前等待所有子进程终止。 AFAICT,不包括等待'过程替换'中的任何过程。

eval操作是必要的,以避免写出100次“相同”代码。 for ((...))循环是C bash循环的for等价物。