I'm using pthreads in a "work crew" pattern where I have a large number of commands to run, and I want to read the output from each command and merge all the outputs. Using pthreads I create one worker thread per core, and each worker thread essentially does the following:
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
}
Both get_from_work_queue
and "enqueue data" require the thread to temporarily acquire a mutex, as the queues are shared, but these mutexes are released before any call to popen()
or fread()
.
My issue is that although I have four cores and four worker threads, only one long-running command is going at any one time. The other three threads are just sitting around, probably waiting to be scheduled.
I assume that something about popen
or fread
is blocking all the threads, and not just the caller. How can I read from a command without blocking other threads, so I can have four long-running commands going at the same time?
select
with a bunch of file descriptors? – Ed Healpopen()
commands running simultaneously from multiple threads works fine. If you backtrace your threads in gdb, where are they stopped? – caf