Изменение программы с использования потоков на использование вилки [закрыто]
Я учусь пользоваться вилками. Задача состояла в том, чтобы создать имитацию работы склада. Производители (в количестве аргв[2]) создают случайное число "товаров" (всего аргв[1]), а потребители (в количестве аргв[3]) получают случайное число этих товаров. Ниже приведен код программы, использующей потоки. Но я пытаюсь сделать то же самое, используя связанные процессы (используя fork()). 2-я версия программы вообще не работает. Производители создают 0 товаров. Я не понимаю, как правильно пользоваться вилкой. Должен ли я каким-то образом убить Чайлдса? Убивают ли они себя после возвращения или продолжают работать до конца? Пожалуйста, помогите мне исправить вторую программу. Вторая программа:
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/mman.h>
#define NBUFF 10
#define MAXNTHREADS 100
#define min( a, b ) ( ( a < b) ? a : b )
int nitems, nproducers, nconsumers;
typedef struct shared_s
{
int buff[NBUFF];
int nput;
int nputval;
int nget;
int ngetval;
sem_t mutex, nempty, nstored;
} sharedtype;
int main(int argc, char **argv)
{
sharedtype * shared;
key_t key;
int shmid, semid;
int i, j, prodcount[MAXNTHREADS], conscount[MAXNTHREADS];
shared = mmap(NULL, sizeof(sharedtype),
PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0);
/* Wrong argv */
if (argc != 4)
{
printf("usage: newconsumer <#items> <#producers> <#consumers>n");
exit(1);
}
nitems = atoi(argv[1]);
nproducers = min(atoi(argv[2]), MAXNTHREADS);
nconsumers = min(atoi(argv[3]), MAXNTHREADS);
pid_t chpidpr [nproducers];
pid_t chpidcon [nconsumers];
/* initilising semaphores */
sem_init(&(shared->mutex), 0, 1);
sem_init(&(shared->nempty), 0, NBUFF);
sem_init(&(shared->nstored), 0, 0);
for (i = 0; i < nproducers; i++) {
prodcount[i] = 0;
switch (chpidpr[i] = fork())
{
case -1:
printf("fork error");
return 1;
case 0:
for (;;)
{
sem_wait(&shared->nempty);
sem_wait(&shared->mutex);
if (shared->nput >= nitems)
{
sem_post(&(shared->nstored));
sem_post(&(shared->nempty));
sem_post(&(shared->mutex));
return 0;
}
shared->buff[(shared->nput) %NBUFF] = shared->nputval;
(shared->nput)++;
(shared->nputval)++;
sem_post(&(shared->mutex));
sem_post(&(shared->nstored));
prodcount[i] += 1;
}
}
}
for (i = 0; i < nproducers; i++)
{
printf("producer count[%d] = %dn", i, prodcount[i]);
}
for (i = 0; i < nconsumers; i++) {
conscount[i] = 0;
switch (chpidcon[i] = fork())
{
case -1:
printf("error");
return 1;
case 0:
for (;;)
{
sem_wait(&(shared->nstored));
sem_wait(&(shared->mutex));
if (shared->nget >= nitems)
{
sem_post(&(shared->nstored));
sem_post(&(shared->mutex));
return 0;
}
j = shared->nget % NBUFF;
if (shared->buff[j] != shared->ngetval)
{
printf("error: buff[%d] = %dn", j, shared->buff[j]);
}
shared->nget++;
shared->ngetval++;
sem_post(&(shared->mutex));
sem_post(&(shared->nempty));
conscount[i] += 1;
}
}
}
for (i = 0; i < nconsumers; i++)
{
printf("consumer count[%d] = %dn", i, conscount[i]);
}
/* destroying semaphores */
sem_destroy(&(shared->mutex));
sem_destroy(&(shared->nempty));
sem_destroy(&(shared->nstored));
exit(0);
}
1 ответ:
Было бы лучше, если бы вы могли предоставить минимальный пример вашего кода. Пока что самая очевидная ошибка, которую я вижу, заключается в том, что ваш
Потоки имеют доступ к одной и той же частной памяти, процессы имеют свою собственную частную память, поэтому она и называется частной.struct {/* .. */} shared
не находится в реальной общей памяти.
fork()
создает копии cow всей памяти, которая явно не помечена как общая. Выделитьshared
в общей памяти было бы первым делом.
mmap/MAP_SHARED
это хорошее начало для программы, которая создает новые процессы черезfork
.struct shared_s {/* .. */} * shared; int main() { shared = mmap(NULL, sizeof(struct shared_s) , PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0); // .... }
Также в случае, если вы работаете на OS X, вам нужно передать дополнительный флаг
MAP_HASSEMAPHORE
, чтобы ваши семафоры работали правильно.