You are most welcome.
The sample actually executes the commands in parallel, but reads the output serially to demonstrate that the output was not intermixed.
Here's a small example of a main that starts a thread for each filename (up to 10) given on the command line. Each thread uses a popen() to cat the file (please no flames about useless uses of cat!!) and reads the data counting the number of times the character 'e' appears in the file. It's a silly (um, useless) programme, because the thread could open and read the file directly, but rather than invoking a ps or netstat command, I wanted something that I could repeat to ensure that the proper number of e's from each file were being counted (to prove no mixing of output from the commands).
The function invoked as the thread sleeps to demonstrate that the threads are indeed created in parallel -- all "create" messages from the main should print before any thread actually announces that it's running the command.
Hope this helps to get you going
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
/*
started as a thread. creates a child process via popen() and reads
the child's output counting the number of target characters (global)
that were in the output. When done, the count is printed on stdout.
A delay of 2s is imposed to demonstrate that the main has started
all threads in parallel, otherwise it is unnecessary.
*/
void *reader( void *data )
{
char target = 'e'; /* count these from the command's output */
char *cmd; /* command to execute */
FILE *rpipe;
char buf[4096]; /* read bufffer */
int tcount = 0; /* count of target */
char *cp; /* pointer as we walk the buffer looking for target */
cmd = (char *) data;
sleep( 2);
fprintf( stderr, "starting the command: %s\n", cmd );
rpipe = popen( cmd, "r" ); /* start the child */
while( fgets( buf, sizeof( buf ), rpipe ) ) /* read all of the child's stdout */
{
cp = buf;
while( (cp = strchr( cp, target )) ) /* count number of target characters in this buffer */
{
tcount++;
cp++;
}
}
pclose( rpipe );
printf( "output from `%s` contained %d '%c' characters\n", cmd, tcount, target );
free( data );
pthread_exit( 0 );
return NULL; /* shouldn't matter, but keeps compilers happy */
}
int main( int argc, char **argv )
{
pthread_t tids[10];
char cbuf[1024];
int i;
if( argc < 2 || argc > 11 )
{
fprintf( stderr, "usage: %s filename1 [filename2... filename10]\n", argv[0] );
exit( 1 );
}
for( i = 1; i < argc; i++ ) /* start all threads to process all files in parallel */
{
snprintf( cbuf, sizeof( cbuf ), "cat %s", argv );
fprintf( stderr, "starting thread: %s\n", cbuf );
pthread_create( &tids[i-1], NULL, reader, (void *) strdup( cbuf ) );
/* thread must free dup to avoid leak */
}
fprintf( stderr, "all threads started, main thread waits....\n" );
for( i = 0; i < argc-1; i++ ) /* wait for all threads to finish */
pthread_join( tids, NULL );
fprintf( stderr, "all threads finished\n" );
return 0;
}