并行代码无需等待

时间:2016-07-26 09:52:28

标签: c++ multithreading concurrency

我正在考虑某种同步原语,但我不知道这种同步被调用了什么,或者这样的事情是否有效。

因此,有一个变量(布尔值)基本上表示一个线程是否仍在处理内存块。在开始时bool设置为false,这意味着工作线程不在你的内存块上工作。现在,主线程为工作线程提供了一个“todo-list”,描述了它应该如何处理该内存块。之后,它将布尔值的状态更改为true,以便工作线程知道现在允许它完成其工作。主线程现在可以继续自己的工作并检查某些位置,如果工作线程现在已经完成工作,例如如果布尔值再次设置为false。如果它是stil true,则主线程只是继续自己的工作而不等待工作线程。如果布尔值为false,则主线程知道工作线程已完成并开始处理内存块。

因此布尔值只是将所有权转移到两个线程之间的内存块上。如果一个线程当前没有该内存的所有权,它只会继续自己的工作,并反复检查它是否现在再次具有所有权。这样,没有一个线程在等待彼​​此,并且可以继续自己的工作。

这叫做什么,这种行为是如何实现的?

编辑:基本上它是一个互斥体。但是,不是等待互斥锁再次解锁,而是继续/跳过关键代码。

2 个答案:

答案 0 :(得分:1)

  编辑:基本上它是一个互斥体。而不是等待互斥锁   再次解锁,它继续/跳过关键代码。

它仍然是一个互斥体,只是"尝试"方法

在标准C ++中,我们讨论std::mutex::try_lock,它试图锁定互斥锁,如果失败则返回false并继续

class unlocker{
 std::mutex& m_Parent;

public : 

unlocker(std::mutex& parent) : m_Parent(parent){}
~unlocker() {m_Parent.unlock(); }

};

std::mutex mtx;
if (mtx.try_lock()){
   unlocker unlock(mtx); // no, you can't use std::lock_guard/unique_lock here
   //success, mtx is free
} else{
  // do something else
}

在Native OS的代码中,您具有类似的功能,具体取决于您所使用的操作系统,例如Unix上的pthread_mutex_trylock和Windows上的TryEnterCriticalSection。不用说标准互斥体可能会在幕后使用这些功能

答案 1 :(得分:0)

如果主线程用完了,你会怎么做?

假设您继续检查并继续阅读true。最终,如果没有工作线程的结果,主线程无法继续。由于你没有更多工作要做,唯一剩下的就是现在不断检查标志的值,浪费其他线程可以用来做有用工作的CPU资源。

一般来说,这不是你想要的。相反,您希望操作系统将主线程置于休眠状态,并且只有在工作线程完成处理后才将其唤醒。随现代操作系统提供的各种锁和信号量都以这种方式工作。在下面有一些内存中的标志,表明谁拥有锁,但是它周围还有一堆逻辑,可以确保操作系统不会安排那些无所事事的线程,而是等待锁准备就绪。

话虽如此,有些情况下这不是你想要的。如果你足够肯定你不会遇到一个线程只是在一个锁上旋转的情况,并且你想要节省操作系统锁的附带的开销,那么只需检查你所描述的标志可能是一个可行的选择。

请注意,像这样的低级别内容应该保留用于特殊情况,而不是工具箱中的第一个工具。最终使用不正确的算法或者实现效率不如您想象的那样容易。如果您决定走这条路,请做好一些认真的工作,让它按预期工作。