【发布时间】:2017-04-24 09:42:33
【问题描述】:
我在“工作组”模式中使用 pthreads,我有大量命令要运行,我想读取每个命令的输出并合并所有输出。使用 pthreads,我为每个内核创建一个工作线程,每个工作线程本质上执行以下操作:
for (;;) {
const char *command = get_from_work_queue();
if (command == NULL)
break;
FILE *fp = popen("long-running-command", "r");
// ... loops reading fp until EOF
// enqueue data read from fp
}
get_from_work_queue 和“入队数据”都需要线程临时获取互斥锁,因为队列是共享的,但这些互斥锁会在任何调用 popen() 或 fread() 之前释放。
我的问题是,虽然我有四个核心和四个工作线程,但任何时候都只有一个长时间运行的命令。其他三个线程只是闲着,可能正在等待调度。
我假设 popen 或 fread 的某些东西阻塞了所有线程,而不仅仅是调用者。如何在不阻塞其他线程的情况下读取命令,这样我就可以同时执行四个长时间运行的命令?
【问题讨论】:
-
为什么不用
select和一堆文件描述符? -
此处接受的答案:popen() alternative 可能值得一试,看看您是否会获得更好/想要的行为。
-
@PhilBrubaker 我不太明白为什么分叉一个额外的外壳会有所作为——而事实是我需要运行外壳。但值得一试。
-
@EdHeal 用 select(2) 编码是一个巨大的痛苦。我真的希望线程具有非阻塞 I/O。但我可能是 SOL。
-
A simple test 表明从多个线程同时运行多个
popen()命令可以正常工作。如果你在 gdb 中回溯你的线程,它们在哪里停止?