制作工人线程?

jma*_*erx 3 c c++ multithreading

有没有办法制作"工作线程"基本上我每次需要时都尝试创建线程,这导致比1线程慢,因为创建新线程总是很昂贵.是否有办法在应用程序首次启动时创建工作线程,然后在必要时让它们工作?

谢谢

pax*_*blo 7

是的,您可以预先创建线程并让它们等待信号开始工作.

这些信号可以是消息队列或信号量或任何其他类型的线程间通信方法.

作为一个例子,我们曾经在UNIX下组建了一个系统,该系统有一个主线程,可以通过网络接收工作并将作业转移到从属线程.从属线程实际上必须通过屏幕抓取(基本上模拟用户)与另一个系统交互以获得他们想要的信息.

换句话说,工作可以比奴隶线程更快地完成.

所以我们启动了大约五十个奇怪的奴隶,并为他们创建了一个条件变量(这是使用pthreads).每个没有进行活动工作的从站只是等待条件变量.

当一个作业进入主线程时,它将相关数据加载到已知存储器中并"踢"条件变量,唤醒其中一个从器件然后抓取工作并开始处理它(在通知主器件之后它可以继续).

因此,在运行中创建线程没有任何开销 - 所有这些都是在应用程序启动时创建的,只是等待工作交付.

当然,这种静态大小的潜在缺点是,如果你真的需要更多的线程,你可能会遇到麻烦.我们通过简单地监视最大线程数来确保解决它,并确保在第二天重新启动进程,如果我们一直在用完则更多.


如果您想要一个更动态的解决方案,您需要研究一个称为线程池的概念.这基本上就是我上面所描述的,但它通常允许您设置最小和最大线程数以及非活动线程在没有工作的情况下生存的最长时间(除非您已经处于最低限度).

它的实现可能很简单:

master:
    minslaves = 7
    maxslaves = 20
    maxtime = 600
    numslaves = 0
    freeslaves = 0

    while running:
        while numslaves < minslaves:
            increment numslaves and freeslaves
            start a slave
        endwhile
        wait for work
        if freeslaves = 0 and numslaves < maxslaves:
            start a slave
        endif
        queue work to slavequeue
    endwhile
    while numslaves > 0:
        wait
    endwhile
    exit
Run Code Online (Sandbox Code Playgroud)

和:

slave:
    while running:
        get work from slavequeue with timeout
        if timed out:
            if time since last work > maxtime and numslaves > minslaves:
                break out of while loop
            endif
            restart while loop
        endif
        decrement freeslaves
        do the work
        increment freeslaves
    endwhile
    decrement numslaves and freeslaves
    exit
Run Code Online (Sandbox Code Playgroud)

(当然,所有共享变量的正确信号保护numslaves,freeslaves,slavequeue和其他人,如果你决定改变他们的主题已开始之后).

并且,如果您的环境已经有线程池,我建议您使用它而不是尝试转换上面的伪代码.我的代码来自内存,旨在说明一点 - 它可能是也可能不是无bug :-)