我有一个名为&#34的项目;一个消费者和一个生产者"。我需要使用信号量和共享内存从文件中逐个读取符号并将它们放入共享内存(在producer.c中),然后读取它们并放入输出文件(在consumer.c中)。程序结束后文件应该相同。
库和全局变量(两个文件都相同):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
key_t keySem;
key_t keySeg;
int segment;
char *address;
int semaphore;
int x;
pid_t w;
所以我在producer.c:
int main() {
srand(time(0));
if((keySeg = ftok(".", 'X')) == -1) end("error - creating a key!\n");
if((segment = shmget(keySeg, sizeof(char), 0777 | IPC_CREAT )) == -1)
end("error - creating a shared memory!\n");
address = shmat(segment,0,0);
if(*address == -1) end("error - getting an address\n");
if((keySem = ftok(".", 'Y')) == -1) end("error - creating a key\n");
if((semaphore = semget(keySem, 2, 0600 | IPC_CREAT )) == -1)
end("error - creating a semaphore!\n");
if((semctl(semaphore, 0, SETVAL, 1)) == -1) end("cant set a semaphore\n");
if((semctl(semaphore, 1, SETVAL, 0)) == -1) end("cant set a semaphore\n");
char sign;
FILE *file;
file = fopen("in", "r");
if(file == NULL) end("error - opening in file\n");
while(fscanf(file, "%c", &sign) != EOF){
semaphore_p(0);
*address = sign;
semaphore_v(1);
}
semaphore_p(0);
*address = EOF;
semaphore_v(1);
fclose(file);
shmdt(address);
exit(0);
}
并在consumer.c:
int main() {
if((keySeg = ftok(".", 'X')) == -1) end("Error - creating a key!\n");
if((segment = shmget(keySeg, 0, 0600 | IPC_CREAT)) == -1)
end("Error - get access to shared memory!\n");
address = shmat(segment,0,0);
if(*address == -1) end("Error - address!\n");
if((keySem = ftok(".", 'Y')) == -1) end("Error - semaphore key!\n");
if((semaphore = semget(keySem, 2, 0600 | IPC_CREAT)) == -1)
end("Error - get access to semaphores!\n");
if((semctl(semaphore, 0, SETVAL, 1)) == -1) end("cant set a semaphore\n");
if((semctl(semaphore, 1, SETVAL, 0)) == -1) end("cant set a semaphore\n");
char sign;
FILE *file;
file = fopen("out", "w");
if(file == NULL) end("error - opening out file\n");
while(sign != EOF) {
semaphore_p(1);
sign = *address;
fputc(sign, file);
printf("[CONSUMER] Sign: %c\n", sign);
semaphore_v(0);
}
fclose(file);
shmdt(address);
shmctl(segment, IPC_RMID, 0);
if((semctl(semaphore, 0, IPC_RMID)) == -1)
end("error - deleting semaphore\n");
exit(0);
}
它们都在处理小文件(低于500个字符),但如果我在文件中添加更多字符,则在semaphore_v(0)之后项目停止(读取几百个字符后)。结果如下: Result
以下是semaphore_p和semaphore_v函数的外观。
static void semaphore_p(int x) {
struct sembuf bufor_sem;
bufor_sem.sem_num=x;
bufor_sem.sem_op=-1;
bufor_sem.sem_flg=0;
while((semop(semaphore, &bufor_sem, 1)) == -1) {
if (errno == ERANGE) {
int a = semctl(semaphore, x, GETVAL);
semctl(semaphore, x, SETVAL, a);
} else if(errno == 4) {
//semaphore_p(x);
} else {
end("ERROR!\n");
}
}
printf("[CONSUMER] Semaphore %d has been closed.\n", x);
}
static void semaphore_v(int x) {
struct sembuf bufor_sem;
bufor_sem.sem_num=x;
bufor_sem.sem_op=1;
bufor_sem.sem_flg=0;
while((semop(semaphore, &bufor_sem, 1)) == -1) {
if (errno == ERANGE) {
int a = semctl(semaphore, x, GETVAL);
semctl(semaphore, x, SETVAL, a);
} else if(errno == 4) {
//semaphore_p(x);
} else {
end("ERROR!\n");
}
}
printf("[CONSUMER] Semafor %d has been opened.\n", x);
}
结束功能
void end(char text[]) {
perror(text);
if(EXIT_FAILURE == 0) exit(0);
exit(EXIT_FAILURE);
}
我已经阅读了有关ERANGE errno的内容,但程序并没有抛出任何错误。 暂停的原因是什么?信号量有某种生命力吗?我怎么能忽略它?
提前感谢您的帮助:)