生产者消费者问题

生产者消费者实验

   程序实现了两个生产者和两个消费者的生产者消费者问题(当生产者消费者数目再多时加上几个子进程就可以了)为了防止程序陷入死循环,给生产者限定了生产次数,同时为了方便截图,将次数限定的比较少。下面是我的程序:  

 

#include <semaphore.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

#include <sys/mman.h>

#include <time.h>  

#define BSIZE 8  

typedef struct

{

    int buffer[BSIZE];

    sem_t lock;

    sem_t nready;

    sem_t nempty;

    int index; //next to put,  next get is index -1

}shared_t;  

int get_one_item(shared_t *ptr)

{

    int rval;

    sem_wait(&ptr->nready);

    sem_wait(&ptr->lock);

    rval = ptr->buffer[--ptr->index];

    sem_post(&ptr->lock);

    sem_post(&ptr->nempty);

    return rval;

}

   

int put_one_item(shared_t *ptr, int pval)

{

    sem_wait(&ptr->nempty);

    sem_wait(&ptr->lock);

    ptr->buffer[ptr->index++] = pval;

    sem_post(&ptr->lock);

    sem_post(&ptr->nready);

    return pval;

}

void err_quit(char *msg)

{

    fprintf(stderr, "%s:%s/n", msg, strerror(errno));

    exit(1);

}

 

 

int main (void)

{

    pid_t pid;

        int j;

    shared_t *ptr;      

    ptr = mmap(NULL, sizeof(shared_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

    if ((int)ptr == -1)

        err_quit("mmap error");  

 

    sem_init(&ptr->lock, 1, 1); /*shared between process, init-value = 1*/

    sem_init(&ptr->nready, 1, 0);

    sem_init(&ptr->nempty, 1, BSIZE);

    setbuf(stdout, NULL);        

 

        //ptr->a=10;  

    pid = fork();

    if (pid < 0)

        err_quit("fork error");

    else if (pid == 0)

    {       /* child 第一个子进程,作为第一个消费者*/

        sleep(2);

        while (1)

        {

            printf("first process %d get value: %d/n", getpid(), get_one_item(ptr));

            usleep(300*1000);

        }

    }

    else

    { 

        int pid1 = fork();      /*第二个子进程,作为第二个消费者*/

        if (pid1< 0)

            err_quit("fork second process error");

        else if (pid1 ==0)

        {

                        sleep(3);

            while (1)

            {

                printf("second process %d get value: %d/n", getpid(), get_one_item(ptr));

                    usleep(300*1000);

            }

        }else

        {

            int pid2=fork();/*第三个子进程,作为生产者*/

            if (pid2< 0)

                err_quit("fork third process error");

            else if(pid2==0)

            {

                srand(time(NULL));

                int val=0;

                for(j=0;j<5;j++)

                              

                               // while(ptr->a)

                                {

                    val = 1+ rand() % 1000;

                    printf("third process put value: %d/n", put_one_item(ptr, val));

                    usleep(300*1000);

                                        //(ptr->a)--;

                }

            }

            else                 /*父进程,生产者*/

            {

                                sleep(1);

                srand(time(NULL));

                int pval = 0;  

                                          

                    //while(ptr->a)//

                              for( j=0;j<5;j++)

                {

                   

                    pval = 1+ rand() % 1000;

                    printf("parent put value: %d/n", put_one_item(ptr, pval));

                    usleep(300*1000);

                                        //(ptr->a)--;

                }

            }

        }

       

    }

       return 0;

}

 

 

 

实验结果的截图:

 

 

通过实验截图中可以看出来:

  1  由于消费者有一定的等待时间,所以生产者总是先于消费者。并且parent也有一定的等待时间,因此third process先执行;同时由于两个消费者等待的时间也不一样,因此两个消费者的消费能力并不一样。

  2   两个生产者都是执行了5次,但由于设置的buffer长度只有8,因此当缓冲区满了后,parent依然有两次没有执行,得等待消费者取走数据之后缓冲区不满再作这两次生产。

这也使我更加深了对共享缓冲区的认识。

  3  两个生产者的数据都是以时间作为种子的rand函数生成的。但在srand之前给parent加上了sleep1),因此两个生产者进程产生的数据并不相同。

   4、从截图中还可以看到,消费者没有完成之有一次命令执行结束的标志:kdlxkdlx-desktop:~桌面$:这是因为但父进程parent结束之后命令就算结束了,子进程还可以在后台做自己的工作。

 

 

    其实程序中还有不如意的地方,就是给两个生产者各自限定了生产次数,我原来的想法是让两个生产者一共生产10次。这就涉及到两个生产者进程间的共享变量问题。让一个共享变量控制两个进程的生产次数,每个进程生产一次都会给变量减1。想到缓冲区是共享的,我就考虑将缓冲区数组的最后一位拿出来作为这个共享的控制变量,但经过多次实验,开始两个生产者进程能够产生设定次数的数据,但当消费者进程启动后,third process进程又开始生产数据,但parent进程就不会再生产了。这样依然是不停的循环。这个问题还得再考虑一下……

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值