DrJessop
DrJessop

Reputation: 472

C program that tells the user which child process finished first

I am working on an assignment that involves using fork. The program runs two separate programs simultaneously and tells the user which one finished first. If a child finishes, the other child still running should be killed immediately. My code so far is this...

int main(int argc, char **argv) {

  if (argc != 2) {
    perror("Invalid number of arguments!");
    exit(1);
  }
  pid_t pid;
  pid_t wpid;
  int status = 0;

  for (int i = 0; i < 2; i++) {
    if ((pid = fork()) == 0) {
      execv("/bin/sh", argv[i+1]);
    } 
  }
  while ((wpid = wait(&status)) > 0);
  printf("%s finished first!", <Insert winning program here>);
  return 0;
}

From my understanding, this runs the programs and will not let the parent process continue until the child processes have finished. Now I'm wondering how I can terminate another child and return the winning process.

Upvotes: 0

Views: 720

Answers (1)

Armali
Armali

Reputation: 19375

But how can I immediately get the pid of the losing process so that I can kill it?

Just as TonyB told: the "parent" saves the pid of the new child. 2) wait will tell you the pid of the winning process. More verbose: Save the PID of both children, wait for any one, compare the return value to (one of) the saved PIDs; the matching one is the winner, the non-matching one is the loser. E. g.:

#define _POSIX_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

int main(int argc, char **argv)
{
  if (argc != 3)    // with two program arguments, argc is 3
    fputs("Invalid number of arguments!\n", stderr), exit(EXIT_FAILURE);
  pid_t pid[2];     // to store both child pids
  pid_t wpid;
  for (int i = 0; i < 2; i++)
    if ((pid[i] = fork()) == 0)
      execl("/bin/sh", "sh", "-c", argv[i+1], NULL),
      perror(argv[i+1]), exit(EXIT_FAILURE);
  wpid = wait(NULL);                    // wait for first
  int wi = wpid==pid[0] ? 0 : 1;        // get index of winner
  kill(pid[!wi], SIGKILL), wait(NULL);  // kill and reap loser
  printf("%s finished first!\n", argv[wi+1]);
  return 0;
}

Upvotes: 1

Related Questions