如何在多线程应用程序中同步双缓冲

发布于 2024-12-23 03:23:28 字数 309 浏览 1 评论 0原文

我有两个线程,一个用于数据采集,另一个用于显示。以避免不必要的同步。我使用双缓冲(或页面翻转)如下:

  1. 数据线程正在写入缓冲区 1,而显示线程正在读取缓冲区 2,
  2. 一旦缓冲区写入完成,数据线程就会切换到另一个缓冲区(缓冲区 2)并开始写入新页面。
  3. 对于读取,如果某个缓冲区正在写入,则显示线程会从另一个缓冲区读取。

它实际上工作得很好,但有时(每 100 帧 1 帧)我可以看到显示屏出现撕裂,这意味着仍然存在竞争条件。

那么我怎样才能实现这种双缓冲的最小(有效)同步呢?伪算法对我来说就足够了。

I have two threads, one for data acquisition and the other one for display. In order to avoid from unnecessary synchronization. I use double buffering (or page flipping) as following:

  1. data thread is writing buffer 1 while display thread reading the buffer 2
  2. once writing is done for a buffer, data thread switches to the other buffer (buffer 2) and starts writing new page.
  3. For reading, if a buffer is in the middle of writing, display thread reads from the other buffer.

It actually works well but sometimes (1 per 100 frames) I can see tearing in the display which means there is still race condition.

So how can I implement minimal (effective) synchronization of this double buffering? A pseudo algorithm would be enough for me.

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

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

发布评论

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

评论(2

疯了 2024-12-30 03:23:28

您可以使用两个信号量来完成此操作。它是生产者/消费者问题的变体。我提供的链接中的伪代码。

You can do this with two semaphores. It is a variation of the Producer/Consumer problem. Pseudo-code in the link I provided.

陪你到最终 2024-12-30 03:23:28

您使用什么语言、平台和(如果需要)图形 API?

伪算法对我来说就足够了。

根据具体情况,方法多种多样,您确实应该更具体。例如,您可以声明临界区,以便线程 1 在写入时等待,而线程 2 正在读取,依此类推 - 但有理由不这样做。

您可以只使用消息传递,这会唤醒绘图线程,而不是使用关键部分。所以它在很大程度上取决于语言、平台和图形 API。

以下是一些使用消息传递来同步渲染并传输到图形的代码:

DataAcquisitionThread.Run() {
  ProcessData();
  Wait(message);
  DrawToBackBuffer();
}

DisplayThread.Run() {
  Wait(message);
  SwapBuffer(message.bufferNumber);
  Render(buffer);
  SendMessage(message.defaultMessage());
}

What language, platform and (if necessary) Graphics API are you working with?

A pseudo algorithm would be enough for me.

There is such a variety in approaches depending on the situation, you really should be more specific. For instance, you can declare critical sections so that thread 1 waits when writing while thread 2 is reading, and so on - but there are reasons not to do that.

You could just work with message passing, which would wake up the drawing thread rather than working with critical sections. So it really depends a great deal on language, platform and graphics API.

Here's some code that uses message passing to synchronize the rendering and transfer to graphics:

DataAcquisitionThread.Run() {
  ProcessData();
  Wait(message);
  DrawToBackBuffer();
}

DisplayThread.Run() {
  Wait(message);
  SwapBuffer(message.bufferNumber);
  Render(buffer);
  SendMessage(message.defaultMessage());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文