winston 发表于 2011-12-20 10:09:05

多线程的那点儿事(之生产者-消费者)

【 声明:版权所有,欢迎转载,请勿用于商业用途。联系信箱:feixiaoxing @163.com】


    生产者-消费者是很有意思的一种算法。它的存在主要是两个目的,第一就是满足生产者对资源的不断创造;第二就是满足消费者对资源的不断索取。当然,因为空间是有限的,所以资源既不能无限存储,也不能无限索取。

    生产者的算法,
view plain

[*]WaitForSingleObject(hEmpty, INFINITE);[*]WaitForSingleObject(hMutex, INIFINITE);[*]/* produce new resources */
[*]ReleaseMutex(hMutex);[*]ReleaseSemaphore(hFull, 1, NULL);
    消费者的算法,

view plain

[*]WaitForSingleObject(hFull, INFINITE);[*]WaitForSingleObject(hMutex, INIFINITE);[*]/* consume old resources */
[*]ReleaseMutex(hMutex);[*]ReleaseSemaphore(hEmpty, 1, NULL);
    那么,有的朋友可能会说了,这么一个生产者-消费者算法有什么作用呢。我们可以看看它在多线程通信方面是怎么发挥作用的?首先我们定义一个数据结构,
view plain

[*]typedef
struct _MESSAGE_QUEUE[*]{[*]    int threadId;[*]    int msgType;[*]    int count;[*]    HANDLE hFull;[*]    HANDLE hEmpty;[*]    HANDLE hMutex;[*]}MESSAGE_QUEUE;
    那么,此时如果我们需要对一个线程发送消息,该怎么发送呢,其实很简单。我们完全可以把它看成是一个生产者的操作。
view plain

[*]void send_mseesge(int threadId, MESSAGE_QUEUE* pQueue, int msg)[*]{[*]    assert(NULL != pQueue);[*]
[*]    if(threadId != pQueue->threadId)[*]      return;[*]
[*]    WaitForSingleObject(pQueue->hEmpty, INFINITE);[*]    WaitForSingleObject(pQueue->hMutex, INFINITE);[*]    pQueue->msgType = msg;[*]    ReleaseMutex(pQueue->hMutex);[*]    ReleaseSemaphore(pQueue->hFull, 1, NULL);      [*]}
    既然前面说到发消息,那么线程自身就要对这些消息进行处理了。
view plain

[*]void get_message(MESSAGE_QUEUE* pQueue, int* msg)[*]{[*]    assert(NULL != pQueue && NULL != msg);[*]
[*]    WaitForSingleObject(pQueue->hFull, INFINITE);[*]    WaitForSingleObject(pQueue->hMutex, INFINITE);[*]    *msg = pQueue->msgType;[*]    ReleaseMutex(pQueue->hMutex);[*]    ReleaseSemaphore(pQueue->hEmpty, 1, NULL);   [*]}

总结:
    (1)生产者-消费者只能使用semphore作为锁
    (2)编写代码的时候需要判断hFull和hEmpty的次序
    (3)掌握生产者-消费者的基本算法很重要,但更重要的是自己的实践

页: [1]
查看完整版本: 多线程的那点儿事(之生产者-消费者)