【问题标题】:Is it ok to use a semphore as a global pause for worker threads?可以使用信号量作为工作线程的全局暂停吗?
【发布时间】:2013-07-28 23:46:35
【问题描述】:

我正在考虑使用信号量作为工作线程池的暂停机制,如下所示:

// main thread
for N jobs:
    semaphore.release()
    create and start worker

// worker thread
while (not done)
    semaphore.acquire()
    do_work
    semaphore.release()

现在,如果我想暂停所有工作人员,我可以获取信号量中可用的全部计数。我想知道它比:

if (paused)
    paused_mutex.lock
    wait for condition (paused_mutex)
do_work

或者有更好的解决方案吗?

我想用信号量做这件事的一个缺点是主线程会阻塞,直到所有工作线程都释放。就我而言,每次迭代的工作单元非常小,因此可能不会成为问题。

更新:澄清一下,我的工作人员是数据库备份,其作用类似于文件副本。当文件被成功复制时,while(not quit) 循环退出。因此,将其与传统的 worker-waits-for-condition 联系起来以获取工作:我的工作人员等待所需的文件副本,而您看到的 while 循环正在执行请求的工作。你可以把我上面的 do_work 想象成 do_piece_of_work。

【问题讨论】:

    标签: multithreading threadpool


    【解决方案1】:

    信号量方法的问题是工作线程必须不断检查工作。它们正在消耗所有可用的 CPU 资源。最好使用互斥锁和条件(信号)变量(如您的第二个示例中所示),以便线程只有在它们有事情要做时才会被唤醒。

    保持互斥锁的时间越短越好。执行此操作的传统方法是创建一个 WORK QUEUE 并使用互斥锁来同步队列插入和删除。主线程插入工作队列并唤醒worker。工作人员获取互斥锁,从队列中删除一个项目,然后释放互斥锁。现在工人执行动作。这最大限度地提高了工作线程和主线程之间的并发性。 这是一个例子:

    // main thread
    create signal variable
    create mutex
    
    for N jobs:
        create and start worker
    
    while (wait for work)
        // we have something to do
        create work item
        mutex.acquire();
        insert_work_into_queue(item);
        mutex.release();
    
        //tell the workers
        signal_condition_variable()
    
    //worker thread
    while (wait for condition)
        mutex.acquire();
        work=remove_item_from_queue();
        mutex.release();
    
        if (work) do(work);
    

    这是一个简单的示例,其中所有工作线程都被唤醒,即使只有一个工作线程实际上会成功地将工作从队列中取出。如果您想要更高的效率,请使用一组条件变量,每个工作线程一个,然后只发出“下一个”的信号,使用“下一个”的算法,您可以根据需要使用简单或复杂的算法。

    【讨论】:

    • 我的工人是数据库备份。他们给了我一个增量的阶梯函数来执行工作,直到他们报告完成。这就是为什么我不想总是等待每次迭代。当然,我可以在工作人员之外设置数据库备份对象,并将它们排队以进行类似于您的代码的增量工作。但是,我希望它们在后台尽可能快地运行,除非发生需要我暂停或停止备份的高优先级事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2016-06-30
    相关资源
    最近更新 更多