Как я могу синхронизировать два потока в Linux C? - PullRequest
0 голосов
/ 27 января 2019

поэтому я бы хотел через этот код синхронизировать два потока.Позвольте мне объяснить, между прочим, я хочу, чтобы thread1 считывал значение с датчика и записывал его в файл с именем "inteers.dat".Таким образом, у thread2 будет задача отправить содержимое, ранее написанное на "Integers.dat", в gnuplot (как указано в коде ниже).Поэтому я бы хотел, чтобы последовательность выполнения потоков была следующей: thread1 (запись), thread2 (отправка), thread1 (запись), thread2 (отправка) и так далее.Я пытался сделать это с мьютексом, но это не сработало.Выполнение обоих потоков всегда случайное.

код: `

     #include <stdio.h>
     #include <pigpio.h>
     #include<sys/types.h>
     #include<signal.h>
     #include<unistd.h>
     #include<pthread.h>
     #include<semaphore.h>

     #define TRIGGER 5
     #define ECHO  6
     void *thread1_process (void *arg);
     void *thread2_process( void *arg);

   double start, stop,  measure;
   int i, val, it=0;
   FILE *fptr;
   FILE *gnu ; 

   static pthread_mutex_t my_mutex11;
   int main(int argc, char *argv[]) {
   pthread_t th1, th2;
  void *ret;
  fptr=fopen("integers.dat", "w");
  gnu = popen("gnuplot -persistent","w");



  pthread_mutex_init (&my_mutex11, NULL); 

  pthread_create(&th1, NULL, thread1_process, NULL);
  pthread_create (&th2, NULL, thread2_process, NULL);   

 (void)pthread_join (th1, &ret);
 (void)pthread_join (th2, &ret);    


   }
   void *thread1_process (void *arg)
  {




  for(int i=0; i<20; i++) 
  {

   pthread_mutex_lock (&my_mutex11);

  printf("thread1 %d \n", i);
  gpioInitialise();
  gpioSetMode(TRIGGER , PI_OUTPUT);  // trigger
  gpioSetMode(ECHO , PI_INPUT);
  gpioWrite(TRIGGER, 0);
  gpioSleep(PI_TIME_RELATIVE, 0, 1);
  gpioWrite(TRIGGER, 1);
  gpioSleep(PI_TIME_RELATIVE, 0, 10); // sleep for 0.00001 seconds
  gpioWrite(TRIGGER, 0);
  while (gpioRead(ECHO) == 0)
  start = time_time();
  while (gpioRead(ECHO) == 1)
  stop = time_time();
  stop=time_time();
  measure = (stop-start) *17100.50;
  it++;
  val=measure;
  fprintf(fptr, "%d %d\n", it, val);
  gpioTerminate();

  pthread_mutex_unlock (&my_mutex11);

   }


  pthread_exit(0);
  }
 void *thread2_process( void *arg)
 {


   for(int j=0; j<20; j++) 
  {

  pthread_mutex_lock (&my_mutex11); 

  printf("thread2 %d \n", j);   
  fprintf(gnu, "%s \n","plot 'integers.dat' with linespoints lw 3");

   pthread_mutex_unlock (&my_mutex11);

  }
   pthread_exit (0);
   }`

Результаты

[thread1 0 
 thread2 0 
 thread2 1 
 thread2 2 
 thread2 3 
 thread2 4 
 thread2 5 
 thread2 6 
 thread2 7 
 thread2 8 
 thread2 9 
 thread2 10 
 thread2 11 
 thread2 12 
 thread2 13 
 thread2 14 
 thread2 15 
 thread2 16 
 thread2 17 
 thread2 18 
 thread2 19 
 thread1 1 
 thread1 2 
 Warning: empty y range [108:108], adjusting to [106.92:109.08]
 libEGL warning: DRI2: failed to authenticate
 thread1 3 
 thread1 4 
 thread1 5 
 thread1 6 
 thread1 7 
 thread1 8 
 thread1 9 
 thread1 10 
 thread1 11 
 thread1 12 
 thread1 13 
 thread1 14 
 thread1 15 
 thread1 16 
 thread1 17 
 thread1 18 
 thread1 19]

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Спасибо за ваши ответы.Я только что нашел решение для синхронизации двух потоков.Должна использоваться опция p_thread, это p_thred_cond.Вы можете следовать руководству по ссылке ниже: https://openclassrooms.com/fr/courses/1513891-la-programmation-systeme-en-c-sous-unix/1514567-les-threads С уважением.

0 голосов
/ 27 января 2019

помимо очевидного "зачем использовать два потока, если один всегда все равно ждет?"вам нужно использовать некоторую переменную «состояния» с мьютексом:

// start here
#define STATE_INITIAL 0
// go here when step 1 finishes
#define STATE_STEP1 1
// go here when step 2 finishes
#define STATE_STEP2 2
pthread_mutex_t my_mutex;
int cur_state;

void wait_my_turn(int desired_state) {
    pthread_mutex_lock(&my_mutex);
    if (cur_state == desired_state) return;
    pthread_mutex_unload(&my_mutex);
}

void finish_turn() {
    ++cur_state;
    if (cur_state == 3) cur_state = 1;
    pthread_mutex_unlock(&my_mutex);
}

// in main, initialize mutex, lock it, and set cur_state to STATE_INITIAL
// until you are ready for threads to start.  Then you need to set it
// to STATE_STEP1 to allow that thread to begin.
// in your threads, begin with wait_my_turn(STATE_STEPn)
// and call finish_turn() when done

... не очень хороший пример, но вы должны понять суть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...