将程序从使用线程更改为使用fork

时间:2014-05-06 13:01:58

标签: c unix pthreads fork

我正在学习使用叉子。任务是创建仓库工作的模拟。生产者(以argv [2]的数量)创建随机数量的商品" (完全是argv [1]),消费者(以argv [3]的数量)获得这些商品的随机数。下面是使用线程的程序代码。但我试图使用相关的proccess(使用fork())来做同样的事情。该计划的第二版根本不起作用。生产者创造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] = %d\n", 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] = %d\n", 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] = %d\n", i, conscount[i]);
    }
    /* destroying semaphores */
    sem_destroy(&(shared->mutex));
    sem_destroy(&(shared->nempty));
    sem_destroy(&(shared->nstored));
    exit(0);
}

1 个答案:

答案 0 :(得分:1)

如果您能提供代码的最小示例,那会更好。到目前为止,我能看到的最明显的错误是你的struct {/* .. */} shared不在实际的共享内存中。

线程可以访问相同的私有内存,进程有自己的私有内存,这就是为什么它被称为私有内存。

fork()创建未明确标记为共享的所有内存的牛副本。在共享内存中分配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,以使你的信号量正常工作。