Настройка семафора и канала для связи процесса - PullRequest
0 голосов
/ 03 декабря 2018

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

  //Semaphore stuff
  key_t key1 = ftok("input.txt", 1);
  int master_sem_id = semget(key1, 1, 0666 | IPC_CREAT);
  senum.val = 0;
  semctl(master_sem_id, 0,  SETVAL, senum);

и установил значение сенума по умолчанию равным 0. (0 означает, что канал пуст, а 1 означает, что канал используется).Затем я настраиваю свои два канала

  int fd1[2];   /* int array that holds the read [0] and write [1] ends of the pipe 1 */
  int fd2[2];   /* int array that holds the read [0] and write [1] ends of the pipe 2 */
  pipe(fd1);    /* Creating the actual pipe 1                         */
  pipe(fd2);    /* Creating the actual pipe 2                         */

, а затем использую один проход канала на стороне записи для программы 1 и на стороне чтения для программы 2. Затем я выполняю программы с помощью вилки

  p1 = fork();
  if(p1 == 0) {
    printf("Executing Program 1.\n");
    snprintf(semaphore1to2, sizeof(semaphore1to2), "%d", master_sem_id); /* Converting the int values to strings */
    snprintf(pipe1Write, sizeof(pipe1Write), "%d", fd1[1]);          /* Converting the int values to strings */
    execl("./program1", inputFile, pipe1Write, semaphore1to2, NULL);
  }  // end p1  = 1
  p2 = fork();
  if(p2 == 0) {
    printf("Executing Program 2.\n");
    snprintf(semaphore1to2, sizeof(semaphore1to2), "%d", master_sem_id); /* Converting the int values to strings */
    snprintf(pipe1Read, sizeof(pipe1Read), "%d", fd1[0]);            /* Converting the int values to strings */
    execl("./program2", semaphore1to2);
  }

В программе 1 я затем читаю из файла и загружаю слова по одному в трубу.Здесь я также использую семафор, чтобы убедиться, что за раз передается только одно слово.(Я также подтвердил, что BUFFER действительно содержит слова).

  while((bytes = read(fileRead, &c, sizeof(c))) > 0) {
    BUFFER[wordLength] = c;
    wordLength++;
    if(c == ' ') {
      while(semctl(semid, 0, GETVAL) == 1) {} //Pipe is being used so cant do anything
      if(semctl(semid, 0, GETVAL) == 0) { //Pipe is empty can be used
        //Write to  pipe here
        close(pipe1Write);
        write(pipe1Write, BUFFER, strlen(BUFFER) + 1); //Write to pipe
                close(pipe1Write);
        memset(&BUFFER[0], 0, sizeof(BUFFER)); //Clear buffer
        wordLength = 0; //Reset count
        senum.val = 1;  //Say that pipe is being written to
        semctl(semid, 0, SETVAL, senum); //exec that command

      }
    }
  }

В конце этой программы 2 предлагается прочитать канал и в данный момент просто распечатать слова.

  if(semctl(sem_id, 0, GETVAL) == 1) { //Pipe is being written to so you need to get info
    //Read from pipe
    char *concat[100];
    read(pipe1Reading, concat, 100);
    printf("PIPE: %s", concat);
    //Close pipe
    close(pipe1Reading);
    senum.val = 0; //Reset that the pipe has bbeen read from and info taken
    semctl(sem_id, 0, SETVAL, senum); //exec command tthat pipe is empty

  }

Этот текущий кадр выполняется, потому что в конце программы 1 я установил правильное значение.Здесь я читаю из трубы и затем пытаюсь распечатать слово.Все, что я получаю для вывода, однако, просто пусто. output В конце этого блока я также установил значение senum val обратно в 0, что должно разорвать цикл в программе 1 и ввести часть, гдеэто пишет снова.Это также не работает для меня.Я протестировал этот метод с двумя простыми программами вывода, и я смог заставить их выполнять друг друга в правильном порядке.На данный момент я заблудился относительно того, что это моя проблема.

...