1
Я написал простую программу потребительского продюсера на C. Он отлично работает, пока у меня 1 производитель и 1 потребитель. Но это странно, когда я увеличиваю количество потребителей.Общая память и семафоры POSIX
- Я начинаю процесс продюсер
- Производитель производит
- Я начинаю процесс потребительского
- Потребитель трудоемкий и производитель производит
- Я не начать процесс интересов потребителей не процесс потребителей 2
- no2 никогда не получает элемент
- Когда я запускаю потребитель №3, №4 ... и так далее, то же самое происходит
Вторая проблема:
- Производитель произвел максимум элементов
- Потребитель потребляет все элементы, но производитель не продолжают производить больше
Я понятия не имею, почему это происходит.
Код:
Производитель:
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <fcntl.h>
#include "common.h"
int memoryID;
struct wrapper *memory;
int rc;
void atexit_function() {
rc = shmctl(memoryID, IPC_RMID, NULL);
rc = shmdt(memory);
sem_destroy(&memory->pmutex);
sem_destroy(&memory->cmutex);
sem_destroy(&memory->empty);
sem_destroy(&memory->full);
}
int main(int argc, char **argv) {
atexit(atexit_function);
//creating key for shared memory
srand(time(NULL));
key_t sharedMemoryKey = ftok(".", MEMORY_KEY);
if (sharedMemoryKey == -1) {
perror("ftok():");
exit(1);
}
memoryID = shmget(sharedMemoryKey, sizeof(struct wrapper), IPC_CREAT | 0600);
if (memoryID == -1) {
perror("shmget():");
exit(1);
}
memory = shmat(memoryID, NULL, 0);
if (memory == (void *) -1) {
perror("shmat():");
exit(1);
}
//initialization
printf("Initializtaion !\n");
memset(&memory->array, 0, sizeof(memory->array));
sem_init(&memory->pmutex, 0, 1);
sem_init(&memory->cmutex, 0, 1);
sem_init(&memory->empty, 0, SIZE_OF_ARRAY);
sem_init(&memory->full, 0, 0);
memory->n = -1;
if (memoryID == -1) {
perror("shmget(): ");
exit(1);
}
while(1)
{
int r = rand();
sem_wait(&memory->empty);
sem_wait(&memory->pmutex);
memory->n++;
(memory->array)[memory->n]=r;
printf("Adding task\t Value:%d\tNumber of tasks waiting:%d \n",r,memory->n);
usleep(10000);
sem_post(&memory->pmutex);
sem_post(&memory->full);
}
}
Потребитель:
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#include <sys/shm.h>
int memoryID;
struct wrapper *memory;
int check_prime(int a);
int main(int argc, char **argv) {
srand(time(NULL));
key_t sharedMemoryKey = ftok(".",MEMORY_KEY);
if(sharedMemoryKey==-1)
{
perror("ftok():");
exit(1);
}
memoryID=shmget(sharedMemoryKey,sizeof(struct wrapper),0);
if(memoryID==-1)
{
perror("shmget(): ");
exit(1);
}
memory = shmat(memoryID,NULL,0);
if(memory== (void*)-1)
{
perror("shmat():");
exit(1);
}
while(1)
{
sem_wait(&memory->full);
sem_wait(&memory->cmutex);
int n = memory->n;
int temp = (memory->array)[n];
printf("Removed item: %d\tPrime:%d\tNumer of tasks left:%d\n",
temp, check_prime(temp),n);
memory->n--;
usleep(10000);
sem_post(&memory->cmutex);
sem_post(&memory->empty);
}
}
common.h:
#define MEMORY_KEY 12
#define SIZE_OF_ARRAY 10
struct wrapper
{
int array[SIZE_OF_ARRAY];
sem_t empty;
sem_t pmutex;
sem_t cmutex;
sem_t full;
int n;
};
Я думаю, вы должны оставить время для другого процесса, чтобы принять РЭМ. Например. спать, пока 1 после семестра. – LPs
К сожалению, это не помогает –
опубликованный код кажется излишне сложным. Кажется, что нет никакой нулевой потребности для любого семафора. Для данных нужны мьютекс, счетчик и массив. потребители должны спать ненадолго, когда объект/int не может обрабатываться. Продюсеру нужно немного поспать, когда массив заполнен. Я бы также предложил, чтобы старые данные не обрабатывались своевременно, чтобы массив рассматривался как круговой список с указателем головы и хвоста – user3629249