嘿,所以我正在做一个简单的生产者问题,但由于某种原因,我的生产者运行,然后我的消费者运行,即使我的生产者一旦无法将信号量初始化为 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);
}else{buffer->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++;
}else{finished = true;}
sem_post(&crit_sec);
sem_post(&empty);
}
}
出于某种原因,在将 15 个字母放入缓冲区后,生产者并未被阻止。
最佳答案
通过消费者调用
sem_post(&empty);
您确保生产者的步骤多于 15 个。
另请注意,在您的 shmget() 调用中您假设
sizeof(int) >= sizeof(struct shared_mem)
这可能是正确的,直到您不向结构添加字段
关于c中的消费者生产者问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22559768/