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

C 读取文件并强制执行进程之间的操作顺序,c,file-io,semaphore,C,File Io,Semaphore,我正试图遵循一个教程,该教程要求我编辑示例代码,让程序运行两个进程,轮流将歌词输出到歌曲(“”) 我的问题是,文件作为一个整体输出,而不是像我所说的那样,它应该看到屏幕截图: 我的代码如下。谢谢 #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> #include <stdlib.h> #define KEY 87654 //Unique

我正试图遵循一个教程,该教程要求我编辑示例代码,让程序运行两个进程,轮流将歌词输出到歌曲(“”)

我的问题是,文件作为一个整体输出,而不是像我所说的那样,它应该看到屏幕截图:

我的代码如下。谢谢

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

    }

  }

}
#包括
#包括
#包括
#包括
#定义键87654//唯一信号量键
int main()
{
int id;/*程序中已知信号量的编号*/
文件*文件;
file=fopen(“207song.txt”,“r”);
INTC;
联合塞蒙{
int-val;
结构semid_ds*buf;
ushort*阵列;
}争论;
argument.val=1;
/*使用外部键创建信号量(如果尚未创建)
存在。请向世界授予权限*/
id=semget(键10666 | IPC|u CREAT);
/*始终检查系统返回*/
if(id<0){
fprintf(stderr,“无法获取信号量。\n”);
出口(0);
}
/*我们实际上得到的是一个信号量数组
semget()的参数是数组维度-在我们的例子中
1. */
/*设置信号量数组中数字0信号量的值
#将id设置为值0*/
if(semctl(id,0,SETVAL,参数)<0){
fprintf(stderr,“无法设置信号量值。\n”);
}否则{
fprintf(stderr,“信号量%d已初始化。\n”,键);
}
int-pid=fork();
常数int HENRY_DONE=0;
const int LIZA_DONE=1;
volatile int flag=HENRY_DONE;
如果(pid){
结构sembuf操作[1];
int retval;/*来自semop()的返回值*/
/*获取具有外部名称键的信号量的索引*/
id=semget(键,10666);
if(id<0){
/*信号量不存在*/
fprintf(stderr,“程序信号找不到信号量,正在退出。\n”);
出口(0);
}
操作[0].sem_num=0;
/*哪个操作?从信号量值中减去1:*/
操作[0]。sem_op=-1;
/*设置标志以便我们等待:*/
操作[0]。sem_flg=0;
而(1){
//过程1
//等等
操作[0]。sem_op=-1;
retval=semop(id,operations,1);
//临界截面
printf(“莉莎的部分:\n”);
fflush(stdout);
睡眠(1);
而((c=getc(文件))!=EOF)
如果(c==“\n”){
普查尔(c);
打破
}
其他的
普查尔(c);
fflush(stdout);
操作[0]。sem_op=1;
//信号
retval=semop(id,operations,1);
}
}否则{
//过程2
结构sembuf操作[1];
int retval;/*来自semop()的返回值*/
/*获取具有外部名称键的信号量的索引*/
id=semget(键,10666);
if(id<0){
/*信号量不存在*/
fprintf(stderr,“程序信号找不到信号量,正在退出。\n”);
出口(0);
}
操作[0].sem_num=0;
/*哪个操作?从信号量值中减去1:*/
操作[0]。sem_op=-1;
/*设置标志以便我们等待:*/
操作[0]。sem_flg=0;
而(1){
//等等
操作[0]。sem_op=-1;
retval=semop(id,operations,1);
//临界截面
printf(“亨利的部分:\n”);
fflush(stdout);
睡眠(1);
而((c=getc(文件))!=EOF)
如果(c==“\n”){
普查尔(c);
打破
}
其他的
普查尔(c);
fflush(stdout);
//信号
操作[0]。sem_op=1;
retval=semop(id,operations,1);
}
}
}

如果您的while循环有:

while ((c = getc(file)) !=EOF)
                if (c == "\n") {
getc返回一个整数,“\n”是char*类型的c字符串。那个 比较将不匹配,导致第一个消费者显示整个文件

你可能想要

c == '\n'

请注意单引号“而不是双引号”单引号将是一个字符,可以与int进行合理比较。

您好,您的答案有效,但现在我收到的输出与我预期的不一样。请参见此处的屏幕截图:预期输出应该类似[亨利:有一个洞……等等,新线莉莎:然后把它修好……等等,新线亨利:…]这个特殊的构造完全跳过了亨利的前两行