我正在try 用信号量实现生产者和消费者的问题.我想我的逻辑是正确的,但是我的代码并没有像预期的那样工作.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#define BUFFER_SIZE 10
int arr[BUFFER_SIZE];
int position;
sem_t *mutex, *empty, *filled;
void* producer(void* args){
printf("Prod starting\n");
int a,b;
sem_getvalue(empty, &a);
sem_getvalue(mutex, &b);
printf("empty : %d mutex : %d\n", a, b);
do{
sem_wait(empty);
sem_wait(mutex);
int new = rand()%2000;
printf("Adding %d to buffer\n", new);
arr[position] = new;
position++;
sem_post(mutex);
sem_post(filled);
}while(1);
}
void* consumer(void* arg){printf("Consumer starting\n");
do{
sem_wait(filled);
sem_wait(mutex);
position--;
printf("Consuming %d from buffer", arr[position]);
arr[position] = 0;
sem_post(mutex);
sem_post(empty);
}while(1);
}
int main()
{
mutex = sem_open("mutex", O_CREAT, 0644, 1);
empty = sem_open("empty", O_CREAT, 0644, BUFFER_SIZE);
filled = sem_open("filled", O_CREAT, 0644, 0);
pthread_t prod, cons;
int a, b,c;
sem_getvalue(empty, &a);
sem_getvalue(filled, &b);
sem_getvalue(mutex, &c);
printf("empty:%d filled:%d mutex:%d\n", a,b,c);
//printf("Producer = %ld Consumer = %ld\n", prod, cons);
pthread_create(&prod,NULL,producer,NULL);
pthread_create(&cons,NULL,consumer,NULL);
pthread_join(prod,NULL);
pthread_join(cons,NULL);
sem_close(mutex);
sem_unlink("mutex");
sem_close(empty);
sem_unlink("empty");
sem_close(filled);
sem_unlink("filled");
return 0;
}
从以下输出得知,信号量未正确初始化:
empty:0 filled:0 mutex:0
Prod starting
empty : 0 mutex : 0
Consumer starting
我不明白为什么信号量没有正确初始化.从手册页:
Sem_t*sem_open(常量字符*名称,int Omark,模式_t模式,无符号整数值);
如果在OFLAG中指定了O_CREAT,则有两个附加参数 必须供应.模式参数指定对 被放在新的信号量上,值 参数指定新信号量的初始值.
注意:我不能使用sem_init,因为最后的代码需要在MacOS上完成.我只是在Linux上用sem_getValue()重新创建它,以了解问题.
在@Pilcrow的建议下,我将这个问题重现为:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t *mutex;
void* thread(void* arg){
printf("Entered thread\n");
sem_wait(mutex);
printf("Hello\n");
sem_post(mutex);
pthread_exit(NULL);
}
int main()
{
mutex = sem_open("mutex", O_CREAT, 0644, 1);
if(mutex == SEM_FAILED){
printf("Failed to create semaphore\n");
return 1;
}
pthread_t id;
pthread_create(&id,NULL,thread,NULL);
pthread_join(id,NULL);
return 0;
}
输出:
Entered thread
线程继续无限期地等待未正确初始化的mutex信号量.