读取文件并强制进程之间的操作顺序

时间:2013-03-28 17:54:15

标签: c file-io semaphore

我正在尝试按照一个教程,要求我编辑示例代码以使程序运行两个进程,轮流将歌词输出到一首歌曲(' There's a hole in the bucket')

我的问题是该文件作为一个整体输出而不是替代它应该看到我正在谈论的屏幕截图:http://imgur.com/NusvhVA

我的代码如下。感谢。

    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <stdio.h>
    #include <stdlib.h>

    #define KEY 87654 //Unique semaphore key

int main()
{
  int id; /* Number by which the semaphore is known within a program */
  FILE *file;
  file = fopen("207song.txt", "r" );
  int c;

  union semun {
    int val;
    struct semid_ds *buf;
    ushort * array;
  } argument;

  argument.val = 1;

  /* Create the semaphore with external key KEY if it doesn't already
     exists. Give permissions to the world. */
  id = semget(KEY, 1, 0666 | IPC_CREAT);

  /* Always check system returns. */
  if(id < 0) {
      fprintf(stderr, "Unable to obtain semaphore.\n");
      exit(0);
  }

  /* What we actually get is an array of semaphores. The second
     argument to semget() was the array dimension - in our case
     1. */

  /* Set the value of the number 0 semaphore in semaphore array
     # id to the value 0. */
  if( semctl(id, 0, SETVAL, argument) < 0) {
      fprintf( stderr, "Cannot set semaphore value.\n");
  } else {
      fprintf(stderr, "Semaphore %d initialized.\n", KEY);
  }

  int pid=fork();


  const int HENRY_DONE = 0;
  const int LIZA_DONE = 1;
  volatile int flag = HENRY_DONE;

  if(pid) {
    struct sembuf operations[1];
    int retval; /* Return value from semop() */

    /* Get the index for the semaphore with external name KEY. */
    id = semget(KEY, 1, 0666);

    if(id < 0){
      /* Semaphore does not exist. */

      fprintf(stderr, "Program sema cannot find semaphore, exiting.\n");
      exit(0);
    }
    operations[0].sem_num = 0;
    /* Which operation? Subtract 1 from semaphore value : */
    operations[0].sem_op = -1;
    /* Set the flag so we will wait : */
    operations[0].sem_flg = 0;

    while(1){
      //Process 1

      //wait
      operations[0].sem_op = -1;
      retval = semop(id, operations, 1);

      //critical section
      printf("Liza's Part: \n");
      fflush(stdout);
      sleep(1);

      while ((c = getc(file)) !=EOF)
                    if (c == "\n") {
                            putchar(c);
                            break;
                            }
                    else
                    putchar(c);
      fflush(stdout);

      operations[0].sem_op = 1;
      //signal
      retval = semop(id, operations, 1);

    }
  }else{
    //Process 2
    struct sembuf operations[1];
    int retval; /* Return value from semop() */
    /* Get the index for the semaphore with external name KEY. */
    id = semget(KEY, 1, 0666);
    if(id < 0){
      /* Semaphore does not exist. */

      fprintf(stderr, "Program sema cannot find semaphore, exiting.\n");
      exit(0);
    }
    operations[0].sem_num = 0;
    /* Which operation? Subtract 1 from semaphore value : */

    operations[0].sem_op = -1;
    /* Set the flag so we will wait : */
    operations[0].sem_flg = 0;

    while(1){

      //wait

      operations[0].sem_op = -1;
      retval = semop(id, operations, 1);

      //critical section

      printf("Henry's Part: \n");
      fflush(stdout);
      sleep(1);


      while ((c = getc(file)) !=EOF)
                    if (c == "\n") {
                            putchar(c);
                            break;
                            }
                    else
                    putchar(c);
      fflush(stdout);

      //signal
      operations[0].sem_op = 1;
      retval = semop(id, operations, 1);

    }

  }

}

1 个答案:

答案 0 :(得分:0)

如果你的while循环有:

while ((c = getc(file)) !=EOF)
                if (c == "\n") {

getc返回一个整数,“\ n”是char *类型的c字符串。那 比较不匹配,导致第一个消费者显示整个文件。

你可能想要

c == '\n'

注意单引号'而不是双引号'单引号将是一个char,它将合理地与int进行比较。