Как я могу использовать futex для синхронизации между двумя независимыми программами?

#multithreading #pthreads #futex

Вопрос:

Я пытаюсь использовать futex системный вызов для синхронизации двух независимых программ на языке си. progA создает несколько потоков и из каждого потока вызывает futex_test . Я пытаюсь убедиться, что progA futex_test за раз запускается только один поток.

Мой подход, поскольку я не могу придумать способ инициализации любой глобальной переменной, которая является общей для этих двух программ, progA создает и записывает 1(available) в общую память. И после вызова futex_test считайте из той же памяти, записывайте 0(unavailable) и вызывайте FUTEX_WAIT системный вызов. Когда закончите, он записывает 1 данные в общую память и вызывает FUTEX_WAKE .

Но это не работает. Я понимаю, что это ошибочная логика. Есть идеи, как это сделать?

Н.Б: Я не хочу вносить какие-либо изменения в «progA». Я могу вносить изменения только в futex_test

прогА.с

 typedef struct file{  int pid; } file_entry;  pthread_t tid[5]; int counter=0;   void write_1_mem(){   int shmid;  int n;  file_entry *entries;   if ((shmid = shmget(20541, sizeof(file_entry)   256, IPC_CREAT | 0666)) == -1) {  printf("problem3");  exit(2);  }   entries = (file_entry *) shmat(shmid, 0, 0);  if (entries == NULL ) {  printf("problem4");  exit(2);  }   int pidD = 1;  entries-gt;pid = pidD;  shmdt(amp;shmid); }    void* trythis(void* arg){  printf("Thread %d createdn",counter);   system("./futex_test");  printf("Thread %d finishedn",counter);  return NULL; }    int main(){  int i = 0;  int error;  int k=0;   write_1_mem();   while (i lt; 5) {  counter=i;   error = pthread_create(amp;(tid[i]),NULL,amp;trythis, NULL);  if (error != 0)  printf("nThread can't be created :[%s]",strerror(error));  i  ;    }   for (k=0;klt;5;k  ){  pthread_join(tid[k], NULL);  }   return 0; }  

futex_test.c

 typedef struct file{  int pid; } file_entry;  // Global variable int shmid; file_entry *entries; static int *ftex;   //system call static int futex(int *uaddr, int futex_op, int val, const struct timespce *timeout, int *uaddr2, int val3 ){  return syscall(SYS_futex,uaddr,futex_op,val,timeout,uaddr,val3); }   void read_shared_mem(){   int n;  if ((shmid = shmget(20541, sizeof(file_entry)   256, IPC_CREAT | 0666)) == -1) {  printf("shmget");  exit(2);  }   entries = (file_entry *) shmat(shmid, 0, 0);  if (entries == NULL) {  printf("problem2");  exit(2);  } }  void write_0_shared_mem(){   if ((shmid = shmget(20541, sizeof(file_entry)   256, IPC_CREAT | 0666)) == -1) {  printf("problem3");  exit(2);  }   entries = (file_entry *) shmat(shmid, 0, 0);  if (entries == NULL ) {  printf("problem4");  exit(2);  }   int pidD = 0;  entries-gt;pid = pidD;  shmdt(amp;shmid); }   void write_1_shared_mem(){   if ((shmid = shmget(20541, sizeof(file_entry)   256, IPC_CREAT | 0666)) == -1) {  printf("problem3");  exit(2);  }   entries = (file_entry *) shmat(shmid, 0, 0);  if (entries == NULL ) {  printf("problem4");  exit(2);  }   int pidD = 1;  entries-gt;pid = pidD;  shmdt(amp;shmid);  }     static void fwait(file_entry *futexp){  int s;  while (1) {  if(futexp-gt;pid==1) {  write_0_shared_mem();  break;  }   s = futex(amp;futexp-gt;pid, FUTEX_WAIT, 0, NULL, NULL, 0);  if (s == -1 amp;amp; errno != EAGAIN)  exit("futex-FUTEX_WAIT");  } }   static void fpost(file_entry *futexp){  int s;   if(futexp-gt;pid==0){  write_1_shared_mem();  s = futex(amp;futexp-gt;pid, FUTEX_WAKE, 1, NULL, NULL, 0);  if (s == -1)  exit("futex-FUTEX_WAKE");  } }   int main(){  int volatile I;  read_shared_mem();  fwait(entries);   for(i=0;ilt;5;i  ){  printf("i=%dn",I);  }   fpost(entries);   return 0;  }  

Выход

 $./progA  Thread 3 created Thread 3 created Thread 4 created Thread 4 created Thread 2 created i=0 i=1 i=2 i=3 i=4 Thread 4 finished i=0 i=1 i=2 i=3 i=4 i=0 i=1 i=2 i=3 i=4 Thread 4 finished Thread 4 finished i=0 i=1 i=2 i=3 i=4 i=0 i=1 i=2 i=3 i=4 Thread 4 finished Thread 4 finished  

Комментарии:

1. Неопределенное поведение для несинхронизированного, не только для чтения, неатомного доступа к объекту из нескольких потоков.