Semaphores for fortran

2019-08-26 21:34发布

问题:

Can anyone help with writing a semaphore function in fortran? I have multiple processes running and I have to synchronize them using semaphore. Such a code could be found for C++ etc., but I could not find any such code for fortran.

If I could call C/C++ function from fortran code, that would also suffice, since C++ semaphore function is already there.

PS: (Additional Explanation) Here is the code which works for C++. I have some fortran applications (as part of standard benchmark) but no semaphore code to synchronize them.

  int get_semaphore ()
  {
   int sem_id;
   sem_id = semget(SEM_ID, 1, IPC_CREAT | 0666);
if (sem_id == -1) {
    perror("get_semaphore: semget");
    exit(1);
}
return sem_id;
}


int set_semaphore (int sem_id, int val)
  { 
   return semctl(sem_id, 0, SETVAL, val);
  }

void decrement_semaphore (int sem_id)
{
 struct sembuf sem_op;
 sem_op.sem_num = 0;
 sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop(sem_id, &sem_op, 1);
 }

 void wait_semaphore (int sem_id)
{   
 struct sembuf sem_op;
sem_op.sem_num = 0;
sem_op.sem_op = 0;
sem_op.sem_flg = 0;
  semop(sem_id, &sem_op, 1);
  } 

Thanks for the help in advance.

回答1:

OpenMP provides semaphores under the term "lock". Normally these aren't used since OpenMP provides higher level tasking constructs, but if you want to do it yourself, that could be a way to do explicit locking/unlocking with Fortran.

P.S. If you want to do it from Fortran by calling the C code that you already have, that could by done by using the ISO C Binding of Fortran 2003. There are many questions/answers here about how this works. I drafted declarations for your Fortran program to match the C routines. These tell the Fortran compiler how to call the C routines using the calling conventions of the C compiler. These are untested and may need debugging:

use iso_c_binding

interface semaphore_stuff

   function get_semaphore () bind (C, name="get_sempaphore")
      import
      integer (c_int) :: get_semaphore
   end function get_semaphore ()

   function set_semaphore (sem_id, int val) bind (C, name="get_sempaphore")
      import
      integer (c_int) :: set_semaphore
      integer (c_int), intent (in), value :: sem_id
      integer (c_int), intent (in) value :: val
   end function set_semaphore

   subroutine decrement_semaphore (sem_id) bind (C, name="decrement_semaphore")
      import
      integer (c_int), intent (in), value :: sem_id
   end subroutine decrement_semaphore

   subroutine wait_semaphore (sem_id) bind (C, name="wait_semaphore")
      import
      integer (c_int), intent (in), value :: sem_id
   end subroutine wait_semaphore

end interface semaphore_stuff