利用信号量解决生产者消费者问题 第2页

利用信号量解决生产者消费者问题 第2页

产品的计数器,计数器的初始值是可利用的资源数目(有界缓冲区的长度)。其次,它是确保产品的生产者和消费者之间动作同步的同步器。生产者要生产一个产品时,首先对资源信号量g_hFullSemaphore和互斥信号量g_hMutex进行P操作,申请资源。如果可以通过的话,就生产一个产品,并把产品送入缓冲区。然后对互斥信号量g_hMutex和资源信号量g_hEmptySemaphore进行V操作,释放资源。

消费者要消费一个产品时,首先对资源信号量g_hEmptySemaphore和互斥信号量g_hMutex进行P操作,申请资源。如果可以通过的话,就从缓冲区取出一个产品并消费掉。然后对互斥信号量g_hMutex和资源信号量g_hFullSemaphore进行V操作,释放资源。如果缓冲区中已经没有可用资源,就把申请资源的进程添加到等待队列的队尾。如果有一个资源被释放,在等待队列中的第一个进程被唤醒并取得这个资源的使用权。

2.文件系统结构

2.1生产者—消费者系统结构

2.1.1 假定缓冲池中有n个缓冲区,每个缓冲区存放一个消息。由于缓冲池是临界资源,它只允许一个生产者投入消息,或者一个消费者从中取出消息。即生产者之间、生产者与消费者之间、消费者之间都必须互斥使用缓冲池。所以必须设置互斥信号量mutex,它代表缓冲池资源,它的数值为1。如下图所示:

2.1.1生产者消费者问题

2.1.2同步问题:

P进程不能往的缓冲区中放产品,设置信号量为s_empty

Q进程不能从的缓冲区中取产品,设置信号量s_full

先设置信号量:s_empty初值为1s_full初值为0

P                              Q

while  (true)                            while  (true) 

{                      

生产一个产品;                      P(s_full);

       P(s_empty);                         从缓冲区取产品;

     送产品到缓冲区;                     V(s_empty);

       V(s_full);                           消费产品;

};                                      };

以上算法可用下图来描述:若图片无法显示请联系QQ3249114

2.1.2生产者消费者单缓冲区

1.P原语操作的主要动作是:

1sem1

2)若sem1后仍大于或等于零,则进程继续执行;

3)若sem1后仍小于零,则该进程被阻塞后与该信号相对应的队列中,然后转进程调度。

P原语操作的功能框图如图1

1  P原语操作功能

2.V原语操作的主要动作是:若图片无法显示请联系QQ3249114

1sem1

2)若相加结果大于零,则进程继续执行;

3)若相加结果小于或等于零,则从该信号的等待队列中唤醒—等待进程,然后再返回原进程继续执行或转进程调度。

V原语操作的功能框图如图2

2  V原语操作功

2.2生产者—消费者存储结构

const unsigned short SIZE_OF_BUFFER = 10;   //缓冲区长度

unsigned short ProductID = 0;    //产品号

unsigned short ConsumeID = 0;   //将被消耗的产品号

unsigned short in = 0;         //产品进缓冲区时的缓冲区下标

unsigned short out = 0;       //产品出缓冲区时的缓冲区下标

int g_buffer[SIZE_OF_BUFFER];    //缓冲区是个循环队列

bool g_continue = true;         //控制程序结束

HANDLE g_hMutex;               //用于线程间的互斥

HANDLE g_hFullSemaphore;      //当缓冲区满时迫使生产者等待

HANDLE g_hEmptySemaphore;    //当缓冲区空时迫使消费者等待

2.3生产者—消费者线程状态

DWORD WINAPI Producer(LPVOID);    //生产者线程

DWORD WINAPI Consumer(LPVOID);   //消费者线程

 

3.核心数据结构及算法说明

3.1数据定义

const unsigned short SIZE_OF_BUFFER = 10;   //缓冲区长度

unsigned short ProductID = 0;    //产品号

unsigned short ConsumeID = 0;   //将被消耗的产品号

unsigned short in = 0;         //产品进缓冲区时的缓冲区下标

unsigned short out = 0;       //产品出缓冲区时的缓冲区下标

 

int g_buffer[SIZE_OF_BUFFER];    //缓冲区是个循环队列

bool g_continue = true;         //控制程序结束

HANDLE g_hMutex;               //用于线程间的互斥

HANDLE g_hFullSemaphore;      //当缓冲区满时迫使生产者等待

HANDLE g_hEmptySemaphore;    //当缓冲区空时迫使消费者等待

 

DWORD WINAPI Producer(LPVOID);    //生产者线程

DWORD WINAPI Consumer(LPVOID);   //消费者线程

3.2算法说明

AND 型信号量解决生产者--消费者问题的算法说明如下:

semaphore mutex=1;

semaphore empty=n;

semaphore full=0;

 

item array[n];

int in=0;

int out=0;

producer()

{

while(ture)

{

     produce an item in next_product;

     Swaite(empty,mutex);

     array[in]=next_product;

     in=(in+1)%n;

     Ssignal(mutex,full);

    }

}

consumer()

{

while(ture)

{

上一页  [1] [2] [3] [4] [5] [6] 下一页

Copyright © 2007-2012 www.chuibin.com 六维论文网 版权所有