Ending the first successful thread in gcc C Linux

2019-09-07 13:39发布

I am an experienced C programmer who has never used threads or parallelism before. I've been reading about it, but I do not see an example of what I want.

I use the gcc C compiler on Mac and linux. I want to replace an important procedure X in my system with a new procedure X2 that will start up two methods, as two threads to be run on two different processors whenever the machine has multiple CPUs (most do these days).

These two methods may share a few global variables, but they will not write to any memory locations other than their own stacks. They will each call many other procedures in the system. I do not envision any other parallel processing.

As soon as either thread finishes, that's it! That's the answer. X2 should immediately kill the other thread and return the answer to whoever called X2.

Maybe I'm naive but I would think this is a well known use of threads. Example code please!

1条回答
一纸荒年 Trace。
2楼-- · 2019-09-07 13:53

I propose to try the following program. It uses two Linux processes to run two procedures, created by a parent process. As soon as one child finishes, the parent gets notified and terminates the other. Studying the documentation for the system calls appearing in the include section is of course necessary to understand the code.

// fork
#include <unistd.h>

// wait, kill
#include <sys/types.h>

// wait
#include <sys/wait.h>

// kill
#include <signal.h>

// exit
#include <stdlib.h>

//printf
#include <stdio.h>

void proc( int id)
{
  int seed= id;
  int count= rand_r( &seed) % 10;
  printf( "\nprocess[%d]: taking %d steps.", id, count);
  int i;
  for ( i= 1; i <= count; ++i) {
    printf( "\nprocess[%d]: step #%d", id, i);
    sleep( 1);
  }
  printf( "\nprocess[%d]:\tfinished.", id);
  exit( 1);
}

int main( int argc, char* argv[])
{
  // create 1st child process
  pid_t p1= fork();
  if ( 0 == p1)
    proc( 1); // child does not return

  // create 2nd child process
  pid_t p2= fork();
  if ( 0 == p2)
    proc( 2); // child does not return

  // this is the parent process
  // wait for a child to terminate
  pid_t p_terminated= wait( NULL); 

  // declare result
  // terminate the other child
  if ( p1 == p_terminated) {
    puts( "\nparent:  \tprocess[1] finished first.");
    kill( p2, SIGKILL);
  }

  if ( p2 == p_terminated) {
    puts( "\nparent:  \tprocess[2] finished first.");
    kill( p1, SIGKILL);
  }
}

On my machine, the program produces the following output:

process[1]: taking 3 steps.

process[2]: taking 7 steps.
process[1]: step #1
process[2]: step #1
process[1]: step #2
process[2]: step #2
process[1]: step #3
process[2]: step #3
process[1]:     finished.
parent:         process[1] finished first.

It is possible for the two processes to finish at the same time so that they both print their "finished" message, but even in this case the parent declares one of them to be the first, and terminates the other.

查看更多
登录 后发表回答