如何有条件地同时多线程和更新变量?

Posted

技术标签:

【中文标题】如何有条件地同时多线程和更新变量?【英文标题】:How can I conditionally multi-thread and update variables at the same time? 【发布时间】:2014-09-12 01:20:45 【问题描述】:

我的代码是:

while (DAQ is ON) 
do stuff on vars;
if(f(vars) > thr)
update vars;

if 条件只会偶尔触发,并且会更新 while 循环前面部分中使用的所有变量。整个循环通常是实时运行的(根据需要),但是当 if 条件也需要运行时就会落后。如何在单独的线程中运行 if 条件?它可能需要它需要的所有时间,如果更新在延迟之后发生,那也没关系。我只希望 while 循环的其余部分实时运行,并且只要“if”线程完成,vars 就会得到更新。

上下文:C++/JUCE 框架,实时信号处理。

【问题讨论】:

问题出在f(vars) 还是更新?如果您将f(vars) 替换为vars 的副本,是否足够快? 没有 if 里面的更新步骤是问题所在。当 if 条件运行时,循环所用的时间会加倍。更新涉及大量矩阵和向量运算。 “f(vars)”只是符号。我的意思是说从 vars 派生的参数是阈值的。 【参考方案1】:

我假设您在这里至少有 2 个内核可以使用。否则,多线程不会对您有太大帮助,如果有的话。我在这里使用 C++11 多线程语义,因此您将在编译器中启用 C++11 语言规范:

#include <condition_variable>
#include <thread>
#include <mutex>

using namespace std;

condition_variable cv;
mutex mtx;
bool ready = false;

void update_vars() 
    while( true ) 
        // Get a unique lock on the mutex
        unique_lock<mutex> lck(mtx);
        // Wait on the condition variable
        while( !ready ) cv.await( mtx );
        // When we get here, the condition variable has been triggered and we hold the mutex
        // Do non-threadsafe stuff
        ready = false;
        // Do threadsafe stuff
    


void do_stuff() 
    while( true ) 
        // Do stuff on vars
        if ( f(vars) ) 
            // Lock the mutex associated with the condition variable
            unique_lock<mutex> lck(mtx); 
            // Let the other thread know we're ready for it
            ready = true;
            // and signal the condition variable
            cv.signal_all();
        
        while( ready ) 
            // Active wait while update_vars does non-threadsafe stuff
        
          



int main() 
    thread t( update_vars );
    do_stuff()

上面的代码 sn-p 所做的就是创建一个运行 update vars 的辅助线程,它会一直等待直到主线程(运行 do_stuff)通过条件变量发出信号。

PS,你可能也可以用期货来做这件事,但我没有与那些足以基于这些回答的人合作。

【讨论】:

假设更新线程需要访问“主”线程产生的一些数据,不是吗? Yakk,这是一个框架。根据 do_stuff() 和 update_vars() 的语义,可能需要额外的同步。例如,update_vars() 可能需要将 vars 复制到一个临时区域,对其进行操作,向主线程发出它已准备好更新 vars 的信号,等待主线程指示它已准备好接收新信息,将信息复制回来,并让主线程知道新信息已经准备好了。 Ken,如果 update_vars() 所做的一切都是非线程安全的,那么情况最终会像以前一样,对吧? do_stuff() 将不得不等待所有 update_vars() 完成。对于我的应用程序,数据是实时的,do_stuff() 需要一次又一次地运行。我希望 do_stuff() 能够简单地启动 update_vars() 而不是等待。稍后对 do_stuff() 的调用可能会检查 update_vars() 是否完成,并且可能会复制更新的变量。

以上是关于如何有条件地同时多线程和更新变量?的主要内容,如果未能解决你的问题,请参考以下文章

多线程之线程同步(互斥锁信号量条件变量和读写锁​)

多线程之线程同步(互斥锁信号量条件变量和读写锁​)

在多线程环境中满足条件(LessThan 常量)时增加变量

JAVA多线程学习九-原子性操作类的应用

[多线程]C++11多线程-条件变量(std::condition_variable)

(转载)Linux 多线程条件变量同步