1. barrier(屏障)
https://www.boost.org/doc/libs/1_77_0/doc/html/thread/synchronization.html#thread.synchronization.barriers.barrier
文档:barrier也被称为等待点(google翻译叫“集合点”,但我认为“等待点”更合理一点),它是多个线程之间的同步点。barrier对象构造时,需要传入需要等待的线程数量(n),这些线程必须全部到达等待点(调用barrier::wait()的位置)后,才能继续往下走,并且barrier被重置。
个人理解:barrier这个词已经很好的能解释它的作用,可以被翻译为“屏障”或者“路障”,也就是当一个线程执行到等待点(调用barrier::wait()的位置),就被“挡”在这里,等待其它的线程也执行到等待点(调用barrier::wait()的位置)。然后,解除“屏障”,各个线程再往下执行。这也是线程同步的一个小trick,很简单,不难理解。
示例:官网没示例,可能是太简单了
2. latch(锁存器)
https://www.boost.org/doc/libs/1_77_0/doc/html/thread/synchronization.html#thread.synchronization.latches
文档:锁存器是一种线程协调机制,它允许一个或多个线程阻塞,直到一个或多个线程到达某个点。(google翻译复制的)
用法:
其一:父线程开启多个子线程执行一些任务(官网说的是:多个线程来执行一个任务,其实执行几个任务都无所谓),然后父线程等待这些子线程执行完,再往下执行。
其二:创建多个线程,在超出公共点之前等待信号。(啥意思,没搞懂)
第一个用途很好理解,很常用的功能,就是多个子线程执行任务,父线程阻塞在调用latch::wait()的位置,当每个子线程调用latch::.count_down()后,latch对象中维护的计数就会减一,直至等0,然后父线程解锁,继续往下执行。
第二个其实就是第一个用法的反过来使用,也就是所有子线程“挡在”latch::wait()的位置,等待其它线程执行latch::.count_down(),直至latch对象中维护的计数等0,然后所有被“挡住”的子线程解锁,继续往下执行。(跟barrier的功能有些类似,只不过barrier是“自动挡”,每次wait(),计数自动减一;而latch是“手动挡”,需要调用latch::.count_down(),计数才会减一)
示例:
用法1:
void DoWork(thread_pool* pool) {
latch completion_latch(NTASKS);
for (int i = 0; i < NTASKS; ++i) {
pool->submit([&] {
// perform work
...
completion_latch.count_down();
}));
}
// Block until work is done
completion_latch.wait();
}
用法2:
void DoWork() {
latch start_latch(1);
vector<thread*> workers;
for (int i = 0; i < NTHREADS; ++i) {
workers.push_back(new thread([&] {
// Initialize data structures. This is CPU bound.
...
start_latch.wait();
// perform work
...
}));
}
// Load input data. This is I/O bound.
...
// Threads can now start processing
start_latch.count_down();
}
网友评论