
PROGRAM MASTER_WORKER
  USE MPI
  INTEGER istatus(MPI_STATUS_SIZE)
  PARAMETER (njobmx=124)
  !     
  CALL MPI_INIT(ierr)
  CALL MPI_COMM_SIZE(MPI_COMM_WORLD,nprocs,ierr)
  CALL MPI_COMM_RANK(MPI_COMM_WORLD,myrank,ierr)

  !=======  MASTER
  !
  !  The master recives the masages from workers and if some worker 
  !  is idle it sends to it a job number. the worker realizes this 
  !  job and sends the massage again to the master. If all jobs are
  !  processed then if the worker has finished the master sends the
  !  term signal (job=-1)  to the worker and the worker exits.
  !
  IF (myrank == 0) THEN

     itag=1
     DO njob=1,njobmx
        CALL MPI_RECV(iwk, 1, MPI_INTEGER, MPI_ANY_SOURCE,  &
             itag, MPI_COMM_WORLD, istatus, ierr)
        idest=istatus(MPI_SOURCE)
        CALL MPI_SEND(njob, 1, MPI_INTEGER, idest,  &
             itag, MPI_COMM_WORLD, ierr)
     END DO

     DO i=1,nprocs-1
        CALL MPI_RECV(iwk, 1, MPI_INTEGER, MPI_ANY_SOURCE,  &
             itag, MPI_COMM_WORLD, istatus, ierr)
        idest=istatus(MPI_SOURCE)
        CALL MPI_SEND(-1, 1, MPI_INTEGER, idest,  &
             itag, MPI_COMM_WORLD, ierr)
     END DO

  ELSE

     !=======  WORKER
     !
     !  The worker sends the signal to the master that it is idle. 
     !  if there are jobs to process then the master sends to the 
     !  worker the job number (njob) and the worker processes the job.
     !  If there are no other jobs the number njob sent to the worker 
     !  is equal to -1 and after reciving it the worker exits.

     itag=1
     iwk=0

     DO
        CALL MPI_SEND(iwk, 1, MPI_INTEGER, 0,  &
             itag, MPI_COMM_WORLD, ierr)
        CALL MPI_RECV(njob, 1, MPI_INTEGER, 0,  &
             itag, MPI_COMM_WORLD, istatus, ierr)
        IF (njob == -1) EXIT

        CALL DOSOMETHING(njob) 

     END DO
     !
     CALL MPI_FINALIZE(ierr)

  END IF

END PROGRAM MASTER


SUBROUTINE DOSOMETHING(JOB)
  !
  ! MAIN JOB
  !
END SUBROUTINE DOSOMETHING
