嘿所以我正在做一个简单的制作人问题,但由于某些原因,我的制作人经历了然后我的消费者运行,即使我的制作人应该停止一旦它无法将信号量初始化为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个字母放入缓冲区后,生产者不会被阻止。
答案 0 :(得分:0)
消费者致电
sem_post(&empty);
你要确保生产者的步骤多于15步。
另请注意,在shmget()调用中,您假设
sizeof(int) >= sizeof(struct shared_mem)
这可能是正确的,直到你没有向结构添加字段
答案 1 :(得分:0)
所以我的解决方案我无法解释,但我在学校运行Windows 7的机器上编译了代码。我使用的是mac。我知道问题在于我用来编译的选项。
我需要在学校计算机上使用该命令:
gcc -o ass3 ass3.c -lpthread -lrt
这使得信号量起作用。这个命令在我的mac上不起作用。显然,-lrt选项不适用于mac。有谁知道为什么或等同于什么,所以我可以在家用电脑上工作?