在多线程程序中实现动态屏障的可能方法

发布于 2024-11-27 11:39:54 字数 414 浏览 2 评论 0原文

我在报纸上读到这个...

因此,我们的工具仅在线程执行时对其进行检查点 在已知的安全点:内核进入、内核退出或某些 我们确定安全的内核中的可中断睡眠。 启动多线程分叉的线程会在 它会等待,直到所有其他线程到达安全点。一旦全部 线程到达屏障,原始线程创建检查点, 然后让其他线程继续执行。

现在我的问题是,谁能猜出作者在谈论什么样的障碍。线程如何创建屏障并在其他线程中动态插入屏障?任何可行的例子都将受到高度赞赏。

已编辑

请不要说使用pthread_barrier_wait,因为这不是问题所在。显然,作者有一个线程可以动态地将屏障插入到其他线程中。我想知道怎么办?

I read this in a paper...

Consequently, our tool only checkpoints a thread when it is executing
at a known safe point: kernel entry, kernel exit, or certain
interruptible sleeps in the kernel that we have determined to be safe.
The thread that initiates a multithreaded fork creates a barrier on
which it waits until all other threads reach a safe point. Once all
threads reach the barrier, the original thread creates the checkpoint,
then lets the other threads continue execution.

Now my question is, can anyone guess what kind of barrier the authors are talking about. How a thread creates a barrier and inserts the barrier dynamically in other threads as well? Any working example will be highly appreciated.

EDITED

Please don't say use pthread_barrier_wait, because that is not the question. Here apparently the authors have a thread that inserts barriers into other threads dynamically. I want to know how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

掐死时间 2024-12-04 11:39:54

您询问的论文似乎是 "Respec: Efficient通过推测和外部决定论进行在线多处理器重放”。论文中提到:

我们修改了 Linux 内核来实现我们的技术。

因此,我们创建了一个新的 Linux 原语,称为多线程分叉,它创建一个与其父进程具有相同线程数的子进程。

所以当报纸上这么说时

Respec 仅在线程在已知安全点执行时对线程进行检查点:内核进入、内核退出或内核中我们确定安全的某些可中断睡眠。启动多线程分叉的线程会创建一个屏障,在该屏障上等待,直到所有其他线程到达安全点。一旦所有线程到达屏障,原始线程就会创建检查点,然后让其他线程继续执行。

我假设他们对 Linux 内核所做的修改中有一个逻辑,即正在记录的进程中的线程在到达这些“安全点”之一时将“进入”屏障(我还假设只有当存在发出“多线程分叉”来创建屏障)。由于这是在内核中发生的,因此很容易实现屏障 - 实际上没有任何动态发生。修改后的内核在这些战略安全点实施了屏障。

我还没有真正读过这篇论文(只是浏览了一些内容)。我并不完全清楚如果一个或多个线程正在执行不需要长时间进入内核的工作会发生什么 - 系统似乎依赖于到达这些显式安全点的线程。因此,线程不应该在 CPU 密集型循环中磨蹭太久(这对于绝大多数程序来说可能不是问题):

请注意,由于我们的屏障实现,一个纪元的实际执行时间可能会比纪元间隔长;在所有线程都到达屏障之前,无法采用检查点。

The paper you're asking about appears to be "Respec: Efficient Online Multiprocessor Replay via Speculation and External Determinism". The paper mentions:

We modified the Linux kernel to implement our techniques.

and

We therefore created a new Linux primitive, called a multithreaded fork, that creates a child process with the same number of threads as its parent.

So when the paper says that

Respec only checkpoints a thread when it is executing at a known safe point: kernel entry, kernel exit, or certain interruptible sleeps in the kernel that we have determined to be safe. The thread that initiates a multithreaded fork creates a barrier on which it waits until all other threads reach a safe point. Once all threads reach the barrier, the original thread creates the checkpoint, then lets the other threads continue execution.

I'd assume that among the modifications they made to the Linux kernel was logic that threads in the process being logged will 'enter' the barrier when they reach one of those "safe points" (I'd also assume only if there's been a 'multithreaded fork' issued to create the barrier). Since this is occurring in the kernel, it would be easy enough to implement a barrier - there's not really anything dynamic going on. The modified kernel has the barriers implemented at those strategic safe points.

I haven't really read the paper (just skimmed a few bits). It's not entirely clear to me what might happen if one or more threads is performing work that doesn't require entering the kernel for a long period of time - it appears that the system depends on the threads getting to those explicit safe points. So threads shouldn't dawdle in a CPU intensive loop for too long (which is probably not an issue for the vast majority of programs):

Note that the actual execution time of an epoch may be longer than the epoch interval due to our barrier implementation; a checkpoint cannot be taken until all threads reach the barrier.

对岸观火 2024-12-04 11:39:54

考虑到您的问题被标记为 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;
}

Well considering that your question is tagged with linux and pthreads, I can only imagine that it's referring to pthread barriers:

Here's an example:

#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;
}
优雅的叶子 2024-12-04 11:39:54

屏障是一个相当标准的同步原语

基本来说,进入屏障后,每个线程都会被阻塞,直到所有相关线程都到达屏障,然后所有线程都被释放。

我知道您问的是 C/C++,但请查看 Java 的 CyclicBarrier 因为这个概念在那里解释得很好。

既然您询问的是 pthreads,请查看 pthread_barrier_init 等人。

编辑

但在这种情况下,线程似乎动态地插入障碍
其他线程。怎么办?

如果没有某种背景(例如您正在阅读的论文),很难回答这个问题。

您引用的摘录给人的印象是这是对某些低级工具的描述,该工具要么插入在某些事件上执行的挂钩(可能在相关线程的上下文中),要么确实在内核模式下运行。不管怎样,它能做到它所说的就不足为奇了。

在我看来,没有人在谈论用户线程动态地将屏障插入到另一个用户线程中。

希望我对上下文的猜测不会离得太远。

A barrier is a fairly standard synchronization primitive.

In basic terms, upon entering a barrier each thread is blocked until all relevant threads have reached the barrier, and then all are released.

I know you're asking about C/C++, but take a look at Java's CyclicBarrier as the concept is explained pretty well there.

Since you're asking about pthreads, take a look at pthread_barrier_init et al.

edit

But in this case, a thread seemingly dynamically inserts barriers in
the other threads. How?

It is hard to answer this without some kind of context (e.g. the paper that you're reading).

The excerpt that you quote gives an impression that this is a description of some low-level tool, that either inserts hooks that get executed on certain events (probably in the context of the threads in question), or indeed operates in kernel mode. Either way, it's little wonder it can do what it says it can.

It doesn't seem to me that anyone is talking about a user thread dynamically inserting barriers into another user thread.

Hope I'm not too far off in my guessing of the context.

惯饮孤独 2024-12-04 11:39:54

简单:使用 pthread_barrier_wait pthread API 调用。

有关详细信息,请参阅手册页: http://linux.die.net/man/3/pthread_barrier_wait

Simple: use the pthread_barrier_wait pthread API call.

See the man page for the details: http://linux.die.net/man/3/pthread_barrier_wait

盗梦空间 2024-12-04 11:39:54

操作系统线程屏障只不过是内存中的某种状态。如果您可以在线程之间共享该状态(通过正确初始化线程),那么线程就可以使用该屏障。

本质上,主线程执行以下操作:

CreateAllThreads(&barrier);
StartAllThreads();
EnterBarrier(&barrier);

所有其他线程执行以下操作:

RuntimeInitialize();
EnterBarrier(&barrier);

以上只是一个非常粗略的伪代码,仅供说明之用。

An OS thread barrier is nothing more than some state in memory. If you can share that state among threads (by properly initializing the threads) then the threads can use that barrier.

Essentially the main thread does:

CreateAllThreads(&barrier);
StartAllThreads();
EnterBarrier(&barrier);

All other threads do:

RuntimeInitialize();
EnterBarrier(&barrier);

The above is only a very rough pseudocode for illustrative purposes only.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文