C 语言中的 POSIX 信号量,用于 2 个独立的程序(消费者/生产者)



我正在尝试用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 %dn", 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 %dn", value);
}
sem_destroy(&sem);
return 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 %dn", 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 %dn", value);
}
sem_destroy(sem);
return 0;
}

我想你会发现他们现在工作得更好。 不过,我建议您遵循我的领导,检查每个返回代码,并在出现任何问题时退出错误。 对于这样的试用代码,这是使其正常运行的最快方法。

感谢您的更正。这非常适合我的目的。 有了sem_init,我应该用 0 作为起始值初始化信号量。 似乎错误是在生产者进程中使用它而不是指针和sem_open。 这是我第一次使用命名信号量,所以不容易看到我的错误。

谢谢

最新更新