设置信号灯和管道以进行过程通信

时间:2018-12-03 17:25:13

标签: c pipe ipc semaphore

我正在做一个需要使用两个信号量和两个管道的任务,以便在程序之间传递信息。在我的主人中,我设置了信号灯键

  //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);

并将默认的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的读端使用一次管道传递。然后,我用fork执行程序。

  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中的循环,并输入再次写入的部分。这对我也不起作用。我用两个简单的输出程序测试了此方法,并能够使它们以正确的顺序相互执行。在这一点上,我不知道我的问题是什么。

0 个答案:

没有答案