设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 开源资讯 查看内容

并发世界中的生产者和消费者模型

2010-10-28 20:52| 发布者: sanool| 查看: 3160| 评论: 2|原作者: 陈莉君

摘要: 每当给学生讲起操作系统中的并发,学生总会以疑惑的神情思考这个貌似陌生的问题。因为从C语言一路走来,程序的执行铁定了是一条一条顺序执行的,即使我们要解决的问题并非线性,但在串行化的世界,我们一定要把复杂 ...

     每当给学生讲起操作系统中的并发,学生总会以疑惑的神情思考这个貌似陌生的问题。因为从C语言一路走来,程序的执行铁定了是一条一条顺序执行的,即使我们要解决的问题并非线性,但在串行化的世界,我们一定要把复杂的问题拉扯成线性。于是乎,串行执行成为理所当然,而并发成为突发而出的概念。可是,回到现实世界看看,并发才是常态。在商品经济的大潮中,有谁告诉该哪些厂家生成多少手机,又有谁告诉多少购买者购何种手机?经济危机又是怎样发生的?计划经济起到怎样的杠杆作用?如此一系列的问题,似乎是社会问题,实际上何尝不是计算机系统中的问题。在操作系统的教科书中,生产者-消费者的经典实例总会粉墨登场,但一般也只是把它作为考试的拦路虎并不与现实实际做过多的联系。而实际上,所谓模型,它抽象了若干种现实实例,反过来说,把这一模型推而广之,可以应用到若干种场合。

  口头上说说这样的模型并非难事,但落实到代码才算从云端踏入大地。好在,每次当我说完云端的概念,有学生总会把它变为代码放在自己的博客上供大家分享。在此,我也从他的博客上搬来用内核线程实现的生产者-消费者模型:

------------------------------------------------------------------------------------------------------------------------------------------------------

   IPC系列文章当中,利用信号量集实现的是用户态下生产者-消费者模型的模型。本文以内核模块的方式,通过创建内核线程来为大家演示内核态下的生产者消费者模型。本模型属于np-nc-nb,即多个生产者多个消费者多个缓冲区。

 

在加载函数中,完成一些初始化的工作,并分别创建了5个生产者线程和消费者线程。kernel_thread函数的第一个参数是所所创建线程要做的动作;通过第二个参数传递i变量。

01

static int __init np_nc_init(void)

02

{

 

03

    int i;

04

 

 

05

    printk("np_nc module is working..\n");

06

    in=out=0;

 

07

    cflag=0;

08

    init_MUTEX(&mutex);

 

09

    sema_init(&s1,BUF_NUM);

10

    sema_init(&s2,0);

 

11

 

12

    for(i=0;i< N;i++)

 

13

    {

14

        index[i]=i+1;

 

15

        kernel_thread(productor_thread,&(index[i]),CLONE_KERNEL);

16

        kernel_thread(consumer_thread,&(index[i]),CLONE_KERNEL);

 

17

    }

18

 

 

19

    return 0;

20

}

在生产者函数中,PNUM是每个生产者要生产货物的数量。语句buf[in]=i*100+(PNUM-p_num+1)即是产生货物的过程。

01

int productor_thread(void *p)

02

{

 

03

    int i=*(int *)p;

04

    int p_num=PNUM;

 

05

 

06

    while(p_num)

 

07

    {

08

        if((s1.count)<=0)

 

09

        {

10

            printk("[producer %d,%d]:I will be waiting for producting..\n",i,s1.count);

 

11

        }

12

        down(&s1);

 

13

            down(&mutex);

14

            buf[in]=i*100+(PNUM-p_num+1);

 

15

            printk("[producer %d,%d]:I producted a goods \"%d\" to buf[%d]..\n",i,s1.count,buf[in],in);

16

                in=(in+1)%BUF_NUM;

 

17

            up(&mutex);

18

            up(&s2);

 

19

        p_num--;

20

    }

 

21

    return 0;

22

}

在消费者函数中,通过一个全局变量CNUM来控制消费者总共的消费次数。


01

int consumer_thread(void *p)

02

{

 

03

    int i=*(int *)p;

04

    int goods;

 

05

 

06

    while(cflag!=CNUM)

 

07

    {

08

        if((s2.count)<=0)

 

09

        {

10

            printk("[consumer %d,%d]:I will be waiting for goods..\n",i,s2.count);

 

11

        }

12

            down(&s2);

 

13

                down(&mutex);

14

            goods=buf[out];

 

15

            printk("[consumer %d,%d]:I consumed a goods \"%d\" from buf[%d]..\n",i,s2.count,goods,(out%BUF_NUM));

16

            out=(out+1)%BUF_NUM;

 

17

                up(&mutex);

18

                up(&s1);

 

19

        cflag++;

20

    }

 

21

    return 0;

22

}

 

  更多内容参看他的博客:http://www.edsionte.com/

 

本文内容由 陈莉君 提供


酷毙

雷人

鲜花

鸡蛋

漂亮

相关阅读

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部