【问题标题】:Is there a set of Win32 API functions to manage synchronized queues?是否有一组 Win32 API 函数来管理同步队列?
【发布时间】:2010-06-16 15:25:31
【问题描述】:

我有一个包含多个工作线程的程序和一个接收作业的主线程。在主线程中,我想将作业排入同步队列,并让工作线程坐在那里等待队列。当队列中有东西时,我希望工作人员从队列中拉出工作,而剩余的工作则坐在那里等待另一个工作。

我找到了 CreateMsgQueue (http://msdn.microsoft.com/en-us/library/ms885180.aspx),但这似乎只存在于 Windows CE 中。

我知道我可以自己写这个,但是如果某些东西已经存在,我会傻到不使用它。

我正在使用 Visual Studio 2005 在 c++ 中进行开发。

任何建议都非常感谢。

谢谢 丰富的

【问题讨论】:

    标签: winapi queue synchronized


    【解决方案1】:

    Windows 无法提供您想要的内容。它提供的是thread pools——有了这些,您不仅不必自己创建队列,而且也不必创建或(直接)管理线程。

    当然,同步队列也确实存在,只是不是 Windows 的一部分。我写的一个是这样的:

    #ifndef QUEUE_H_INCLUDED
    #define QUEUE_H_INCLUDED
    
    #include <windows.h>
    
    template<class T, unsigned max = 256>
    class queue { 
        HANDLE space_avail; // at least one slot empty
        HANDLE data_avail;  // at least one slot full
        CRITICAL_SECTION mutex; // protect buffer, in_pos, out_pos
    
        T buffer[max];
        long in_pos, out_pos;
    public:
        queue() : in_pos(0), out_pos(0) { 
            space_avail = CreateSemaphore(NULL, max, max, NULL);
            data_avail = CreateSemaphore(NULL, 0, max, NULL);
            InitializeCriticalSection(&mutex);
        }
    
        void push(T data) { 
            WaitForSingleObject(space_avail, INFINITE);       
            EnterCriticalSection(&mutex);
            buffer[in_pos] = data;
            in_pos = (in_pos + 1) % max;
            LeaveCriticalSection(&mutex);
            ReleaseSemaphore(data_avail, 1, NULL);
        }
    
        T pop() { 
            WaitForSingleObject(data_avail,INFINITE);
            EnterCriticalSection(&mutex);
            T retval = buffer[out_pos];
            out_pos = (out_pos + 1) % max;
            LeaveCriticalSection(&mutex);
            ReleaseSemaphore(space_avail, 1, NULL);
            return retval;
        }
    
        ~queue() { 
            DeleteCriticalSection(&mutex);
            CloseHandle(data_avail);
            CloseHandle(space_avail);
        }
    };
    
    #endif
    

    【讨论】:

    • 感谢 Jerry,非常好的解决方案。我想我更喜欢你的队列而不是线程池。
    • 您也可以使用完成端口实现几乎相同的效果。几年前我写了一个例子来展示如何做到这一点:blogs.msdn.com/b/larryosterman/archive/2004/03/29/101329.aspx
    • 我和拉里一起做这个。不要重新发明轮子:完成端口已经实现了队列作业调度机制。
    • 我和克里斯和拉里在一起。使用完成端口。
    • @Chris, Len:重新发明轮子并没有错,尤其是当您要替换的轮子是矩形时。
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多