我试图在C中实现生产者/消费者问题。我知道如何使用" fork"来处理它,但在这种情况下,我将实现两个程序。一个用于生产者,一个用于消费者。 对于生产者:信号量必须初始化并且在循环中(到100),信号量应增加其值并打印出来。这已经很好了。 对于消费者:在生产者中初始化的信号量应打开并在循环中(至10)其值应减少并打印。 当我为消费者运行该过程时:打印内存访问错误。 我完全不知道,我做错了什么。谢谢你的帮助!
消费者:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int value;
sem_t *mySem = sem_open("sem", O_CREAT|O_EXCL , S_IRUSR|S_IWUSR , 0);
for(int i=0; i < 10; i++) {
sem_wait(mySem);
sem_getvalue(mySem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_close(mySem);
sem_unlink("sem");
return 0;
}
生产者:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
sem_t sem;
int main() {
sem_init(&sem, 0, 0);
int value;
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(&sem);
sem_getvalue(&sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(&sem);
return 0;
}
答案 0 :(得分:0)
sem_init(&sem, 0, 0);
做什么? sem
与消费者有什么关系?
对于通过任何 n IPC进行通信的两个不相关的进程,他们必须按名称就资源达成一致。如果他们共享文件,则为真。如果他们共享一个信号量也是如此。这就是命名信号量的用途。
我修改了你的程序以使用一个命名的信号量。制作人创造并独家拥有它;消费者如果不存在则会出错。
消费者:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/types.h>
static const char name[] = "sem";
int main() {
int value;
sem_t *sem = sem_open(name, 0, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 10; i++) {
sem_wait(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
if( -1 == sem_close(sem) ) {
err(EXIT_FAILURE, "sem_close");
}
if( -1 == sem_unlink(name) ) {
err(EXIT_FAILURE, "sem_unlink");
}
return 0;
}
制片:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static const char name[] = "sem";
int main() {
sem_unlink(name); // ignore error if not extant
int value;
sem_t *sem = sem_open(name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(sem);
return 0;
}
我认为你现在发现它们的效果会更好。不过,我建议你遵循我的主导,并检查每个返回代码,并在出现任何问题时退出。对于像这样的试用代码,这是使其正常运行的最快方法。
答案 1 :(得分:0)
感谢您的纠正。这完全符合我的目的。 使用sem_init我应该用0作为Start-Value来初始化信号量。 似乎错误是在生产者进程中使用它而不是指针和sem_open。 这是我第一次使用命名信号量的经历,因此很难看到我的错误。
非常感谢