在java中,多个线程可以在某个点等待所有其他线程,这样在所有其他线程完成第一个块之前它们不会启动新的代码块:
CyclicBarrier barrier = new CyclicBarrier(2);
// thread 1
readA();
writeB();
barrier.await();
readB();
writeA();
// thread 2
readA();
writeB();
barrier.await();
readB();
writeA();
是否可以完全或轻松地转换为C ++?
同样使用OpenCL,也有类似的指令:
readA();
writeB();
barrier(CLK_GLOBAL_MEM_FENCE);
readB();
writeA();
所以所有邻居线程都互相等待,但它只是一个受约束的C实现。
答案 0 :(得分:1)
C ++ STL没有循环屏障。您可以向标准委员会提出建议:)
像Oracle或Microsoft这样的公司可以快速决定添加到其语言库中的内容。对于C ++,人们必须达成协议,这可能需要一段时间。
256个线程很多。与所有与性能相关的问题一样,您需要测量代码以做出明智的决策。有256个线程,我很想使用由第11个障碍同步的10个障碍。你需要衡量一下,知道这是否真的更好。
在Java的启发下,查看我的C ++循环障碍实现。几年前我写的。它是基于我在http://studenti.ing.unipi.it/~s470694/a-cyclic-thread-barrier/找到的其他人(错误)代码(链接不再起作用......)代码非常简单(不需要归功于我)。当然,它是原样,没有保证。
// Modeled after the java cyclic barrier.
// Allows n threads to synchronize.
// Call Break() and join your threads before this object goes out of scope
#pragma once
#include <mutex>
#include <condition_variable>
class CyclicBarrier
{
public:
explicit CyclicBarrier(unsigned numThreads)
: m_numThreads(numThreads)
, m_counts{ 0, 0 }
, m_index(0)
, m_disabled(false)
{ }
CyclicBarrier(const CyclicBarrier&) = delete;
CyclicBarrier(CyclicBarrier &&) = delete;
CyclicBarrier & operator=(const CyclicBarrier&) = delete;
CyclicBarrier & operator=(CyclicBarrier &&) = delete;
// sync point
void Await()
{
std::unique_lock<std::mutex> lock(m_requestsLock);
if (m_disabled)
return;
unsigned currentIndex = m_index;
++m_counts[currentIndex];
// "spurious wakeup" means this thread could wake up even if no one called m_condition.notify!
if (m_counts[currentIndex] < m_numThreads)
{
while (m_counts[currentIndex] < m_numThreads)
m_condition.wait(lock);
}
else
{
m_index ^= 1; // flip index
m_counts[m_index] = 0;
m_condition.notify_all();
}
}
// Call this to free current sleeping threads and prevent any further awaits.
// After calling this, the object is no longer usable.
void Break()
{
std::unique_lock<std::mutex> lock(m_requestsLock);
m_disabled = true;
m_counts[0] = m_numThreads;
m_counts[1] = m_numThreads;
m_condition.notify_all();
}
private:
std::mutex m_requestsLock;
std::condition_variable m_condition;
const unsigned m_numThreads;
unsigned m_counts[2];
unsigned m_index;
bool m_disabled;
};
答案 1 :(得分:1)
您可以在boost库中找到它,其名称仅为barrier,并且没有等待超时选项。