信号化线程以启动特定功能

Posted

技术标签:

【中文标题】信号化线程以启动特定功能【英文标题】:Signalize thread to start specific function 【发布时间】:2012-08-20 06:21:52 【问题描述】:

我想将一些 CPU 密集型作业拆分为多个线程。我想用 4 个线程创建一个线程池。

我想知道快速完成以下操作的方法:

    检查是否有一个线程可用于接收处理 向一个线程发出信号以启动特定功能 等待所有线程完成它们的工作

这应该尽可能快。我在 Windows 7 上的 Visual Studio 2010 中使用 C++。如果它比可移植方法更快,任何 Win7/VS2010 特定的解决方案都将是首选。

编辑: 我在 MSDN 上找到了这个示例:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686946(v=vs.85).aspx

有没有更快的方法来做到这一点?

【问题讨论】:

示例代码每次都会创建线程并等待它们终止。那不会是高性能:( 【参考方案1】:

Boost 线程库中的内容非常快。您可以启动 4 个线程,最终等待 boost::condition_variable。在主线程中,您可以将内容添加到任务队列,然后调用 boost::condition_variable::notify_one 以启动一个空闲线程(如果有)。一旦通知其中一个工作线程,它就会从任务队列中取出东西并继续这样做,直到队列为空。为了等待任务队列完成,让使任务队列为空的线程调用 boost::condition_variable::notify_all 并在主线程中等待该信号。显然,您需要使用互斥锁来保护这些东西的共享数据。

如果您有中型到大型的任务并且应该在一秒钟内执行几千个或更少的任务,这种技术就可以很好地工作。我没有使用这种技术处理较小任务的经验。

并行模式库 (PPL) 也非常擅长这些东西,它为您做了很多事情,但您没有那么多的控制权。它仅适用于 Windows,但这对您来说似乎没问题。 ;)


编辑:您的链接似乎是一个很好的解决方案。使用 WINAPI 通常是您能做的最快的事情,因为其他 API 通常是基于它构建的。然而,WINAPI 并没有提供很好的抽象。因此,我更喜欢 PPL、期货等来执行这样的任务。你的任务有多大?如果它们花费的时间超过几毫秒,那么您不必担心您正在使用的 api,因为这不是瓶颈。

【讨论】:

【参考方案2】:

第一种方式:Asynchronous Procedure Calls.

另一种方式:I/O Completion Ports,可用于您的任务。

【讨论】:

I/O 完成端口队列比窗口消息队列慢。【参考方案3】:

我不知道 Visual C++ 特定的线程池,但是我听说过一些 ppl.h 的存在。我用过一个非官方的boost threadpool。和所有其他 boost 它在 Visual Studio 中编译得很好

【讨论】:

【参考方案4】:

试试看

class SimpleTask: public tbb::task 

public:
    SimpleTask(const char *c ) 
    task* execute() 
        //do task
        return 0;
    
;
//execute tasks and wait
    tbb::task_scheduler_init init(50);//initialize pool
        tbb::task_list list;

        for(int i=0;i<30;i++)//create 30 task

            list.push_back(*new(tbb::task::allocate_root()) SimpleTask());
        

tbb::task::spawn_root_and_wait(list);//execute and wait for all task or call spawn without wait

【讨论】:

以上是关于信号化线程以启动特定功能的主要内容,如果未能解决你的问题,请参考以下文章

如何向 Qt 中 QThread 类的特定对象发出信号?

QT 信号槽 异步事件驱动 单线程 多并发

两个不同类别的信号和插槽

线程 1:信号 sigabrt。不知道如何解决这个问题

QtSerialPort 在错误的线程中实例化,导致信号/插槽失败

QTimer没有在线程中触发