我正在做一个需要使用两个信号量和两个管道的任务,以便在程序之间传递信息。在我的主人中,我设置了信号灯键
//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的末尾我设置了适当的值。在这里,我正在从管道中读取内容,然后尝试打印出该单词。但是,我得到的所有输出都是空的。在此块的末尾,我还将senum val设置回0,这将中断程序1中的循环,并输入再次写入的部分。这对我也不起作用。我用两个简单的输出程序测试了此方法,并能够使它们以正确的顺序相互执行。在这一点上,我不知道我的问题是什么。