c中的消费者生产者问题
Posted
技术标签:
【中文标题】c中的消费者生产者问题【英文标题】:Consumer Producer issue in c 【发布时间】:2014-03-21 13:11:35 【问题描述】:嘿,所以我正在做一个简单的生产者问题,但由于某种原因,我的生产者运行通过,然后我的消费者运行,即使我的生产者一旦无法将信号量初始化为 15 就应该停止:
#define _REENTRANT
#define BUFFER_SIZE 15
#define SHMKEY ((key_t) 7890)
//The buffer should be treated as circular buffer
#define BUFFER_WRAP(x) x%BUFFER_SIZE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdbool.h>
//headers
void* producerFunc(void *);
void* consumerFunc(void *);
//Structures
typedef struct
char* value;
shared_mem;
typedef struct
int value;
shared_dat;
//You will require 3 semaphores;
sem_t empty;
sem_t full;
sem_t crit_sec;
int start = 0;
int end = 0;
shared_mem *buffer;
//while(fscanf(fp,"%c",&newChar) != EOF)
char newChar;
FILE* fp;
shared_dat *counter;
//To compile program use the command:
//gcc name_of_program.c -lpthread -lrt
int main(void)
fp = fopen("mytest.dat", "r");
/******************init everything: threads, sems, shmem**********/
int r=0;
int i;
int shmid; /* shared memory ID */
pthread_t producer[1]; /* process id for thread 1 */
pthread_t consumer[1]; /* process id for thread 2 */
pthread_attr_t attr; /* attribute pointer array */
int status;
char *shmadd;
shmadd = (char *) 0;
int value, value1;
//create shared memory seg, if return -1 then print error
if ((shmid = shmget (SHMKEY, sizeof(int), IPC_CREAT | 0666)) < 0)
perror ("shmget");
exit (1);
//connect process to shared memory segment. If return is -1 then print error
if ((buffer = (shared_mem *) shmat (shmid, shmadd, 0)) == (shared_mem *) -1)
perror ("shmat");
exit (0);
//set the
char buffer_array[15];
buffer->value = buffer_array;
counter = (shared_dat *) malloc(sizeof(shared_dat));
/* initialize shared memory to 0 */
counter->value = 0 ;
sem_init(&empty,0,BUFFER_SIZE);
sem_init(&full,0,0);
sem_init(&crit_sec,0,1);
printf("1 - I am here %d in pid %d\n",r,getpid());
fflush(stdout);
/* Required to schedule thread independently.
Otherwise use NULL in place of attr. */
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); /* system-wide contention */
/* end to schedule thread independently */
/* Create the threads */
pthread_create(&producer[0], &attr, producerFunc, NULL);
pthread_create(&consumer[0], &attr, consumerFunc, NULL);
/* Wait for the threads to finish */
pthread_join(producer[0], NULL);
pthread_join(consumer[0], NULL);
/***************once threads finished and * reached in buffer************/
printf("from parent counter = %d\n", counter->value);
printf("---------------------------------------------------------------------------\n");
printf("\t\t End of simulation\n");
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&crit_sec);
//release shared mem with IPC_RMID and print "end"
if ((shmctl (shmid, IPC_RMID, (struct shmid_ds *) 0)) == -1)
perror ("shmctl");
exit (-1);
fclose(fp);
exit(0);
void* producerFunc(void *arg)
bool finished = false;
while(!finished)
sem_wait(&empty);
sem_wait(&crit_sec);
end++;
if(fscanf(fp,"%c",&newChar) != EOF)
buffer->value[BUFFER_WRAP(end)] = newChar;
printf("%c",newChar);
elsebuffer->value[BUFFER_WRAP(end)] = '*';
finished = true;
sem_post(&crit_sec);
sem_post(&full);
void* consumerFunc(void *arg)
bool finished = false;
char val;
while(!finished)
sem_wait(&full);
sem_wait(&crit_sec);
start++;
//sleep for 1 sec
sleep(1);
if((val = buffer->value[BUFFER_WRAP(start)]) != '*')
printf("Consuming: %c\n",val);
counter->value++;
elsefinished = true;
sem_post(&crit_sec);
sem_post(&empty);
由于某种原因,在将 15 个字母放入缓冲区后,生产者并未被阻塞。
【问题讨论】:
【参考方案1】:消费者调用
sem_post(&empty);
您要确保生产者的步骤超过 15 个。
另请注意,在您的 shmget() 调用中,您假设
sizeof(int) >= sizeof(struct shared_mem)
这可能是正确的,直到您不向结构中添加字段
【讨论】:
有谁知道为什么 -lrt 选项在 mac 上不起作用?这就是让我的代码在 Windows 计算机上运行的原因。【参考方案2】:所以我无法准确解释我的解决方案,但我在学校运行 Windows 7 的机器上编译了代码。我使用的是 mac。我知道问题出在我用来编译的选项上。
我需要在学校电脑上使用命令:
gcc -o ass3 ass3.c -lpthread -lrt
这使信号量起作用。同样的命令在我的 mac 上不起作用。显然 -lrt 选项在 mac 上不起作用。有谁知道为什么或等价物是什么,所以我可以让它在我的家用电脑上工作?
【讨论】:
以上是关于c中的消费者生产者问题的主要内容,如果未能解决你的问题,请参考以下文章