我在一篇论文中读到了这个......
因此,我们的工具仅在执行时检查线程 在已知的安全点:内核入口,内核退出或确定 我们已经确定安全的内核中断了睡眠。 启动多线程fork的线程会创建一个屏障 在所有其他线程达到安全点之前等待它。一切都好 线程到达屏障,原始线程创建检查点, 然后让其他线程继续执行。
现在我的问题是,有人可以猜出作者正在谈论什么样的障碍。线程如何创建屏障并在其他线程中动态插入屏障?任何工作实例都将受到高度赞赏。
EDITED
请不要说使用 pthread_barrier_wait ,因为这不是问题。显然,作者有一个线程可以动态地将障碍插入到其他线程中。我想知道怎么做?
答案 0 :(得分:4)
您询问的论文似乎是"Respec: Efficient Online Multiprocessor Replay via Speculation and External Determinism"。该文件提到:
我们修改了Linux内核以实现我们的技术。
和
因此,我们创建了一个名为多线程fork的新Linux原语,它创建了一个与其父级具有相同线程数的子进程。
所以当论文说明
时Respec仅检查在一个已知安全点执行时的线程:内核条目,内核退出或内核中我们确定为安全的某些可中断睡眠。启动多线程分支的线程会创建一个屏障,等待所有其他线程到达安全点。一旦所有线程都到达屏障,原始线程就会创建检查点,然后让其他线程继续执行。
我认为他们对Linux内核进行的修改之中的逻辑是,正在记录的进程中的线程在到达其中一个“安全点”时将“进入”障碍(我还假设只有发布了一个“多线程分叉”来创建屏障)。由于这是在内核中发生的,因此很容易实现一个障碍 - 实际上并没有任何动态。修改后的内核在这些战略安全点上实施了障碍。
我还没读过这篇论文(只是略微浏览了一下)。我不完全清楚,如果一个或多个线程正在执行不需要长时间进入内核的工作,可能会发生什么 - 看起来系统依赖于线程到达那些显式安全点。所以线程不应该在CPU密集型循环中磨损太长时间(这对于绝大多数程序来说可能不是问题):
请注意,由于我们的屏障实施,时期的实际执行时间可能比时期间隔长;在所有线程都到达屏障之前,不能使用检查点。
答案 1 :(得分:2)
考虑到你的问题用linux和pthreads标记,我只能想象它指的是pthread障碍:
以下是一个例子:
#include <pthread.h>
#include <stdio.h>
pthread_barrier_t bar;
pthread_t th;
void* function(void*)
{
printf("Second thread before the barrier\n");
pthread_barrier_wait(&bar);
printf("Second thread after the barrier\n");
return NULL;
}
int main()
{
printf("Main thread is beginning\n");
pthread_barrier_init(&bar, NULL, 2);
pthread_create(&th, NULL, function, NULL);
pthread_barrier_wait(&bar);
printf("Main thread has passed the barrier\n");
pthread_join(&th,NULL);
pthread_barrier_destroy(&bar);
return 0;
}
答案 2 :(得分:0)
屏障是fairly standard synchronization primitive。
从基本的角度来说,一旦进入障碍,每个线程都会被阻塞,直到所有相关线程都到达障碍,然后全部被释放。
我知道你在询问C / C ++,但是看看Java CyclicBarrier
,因为这个概念很好地解释了。
既然您在询问pthreads,请查看pthread_barrier_init
等。
修改强>
但在这种情况下,一个线程似乎动态地插入障碍 其他线程。怎么样?
如果没有某种背景(例如您正在阅读的论文),很难回答这个问题。
您引用的摘录给人的印象是,这是对某些低级工具的描述,要么插入在某些事件上执行的钩子(可能在相关线程的上下文中),要么实际在内核中运行模式。无论哪种方式,它都可以做到它所能做的事情,这一点也就不足为奇了。
在我看来,没有人在谈论用户线程动态地将障碍插入另一个用户线程。
希望我在猜测背景时不会太离谱。
答案 3 :(得分:-1)
简单:使用pthread_barrier_wait pthread API调用。
有关详细信息,请参见手册页:http://linux.die.net/man/3/pthread_barrier_wait
答案 4 :(得分:-1)
OS线程障碍只不过是内存中的某种状态。如果您可以在线程之间共享该状态(通过正确初始化线程),则线程可以使用该障碍。
基本上主线程是:
CreateAllThreads(&barrier);
StartAllThreads();
EnterBarrier(&barrier);
所有其他线程:
RuntimeInitialize();
EnterBarrier(&barrier);
以上只是一个非常粗糙的伪代码,仅供说明之用。