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