通知另一个线程数据可用的最快方法是什么?任何纺纱的替代品?

jav*_*red 8 c++ multithreading

我的一个线程将数据写入循环缓冲区,另一个线程需要尽快处理此数据.我想写这么简单spin.伪代码!

    while (true) {
        while (!a[i]) {
            /* do nothing - just keep checking over and over */
        }
        // process b[i]
        i++;
        if (i >= MAX_LENGTH) {
            i = 0;
        }
    }
Run Code Online (Sandbox Code Playgroud)

上面我a用来表示存储的数据b可供处理.Probaly我也应该为这种"热"过程设置线程.当然这种旋转在CPU方面非常昂贵,但对我来说这是好的,因为我的主要要求是延迟.

问题是 - 我应该写出类似的东西,boost或者stl允许以下内容:

  1. 更容易使用.
  2. 在占用较少CPU资源的同时,延迟大致相同(甚至更好)?

我认为我的模式非常普遍,某些地方应该有一些好的实现.

upd似乎我的问题仍然太复杂了.让我们考虑一下这种情况,当我需要以任意顺序将一些项目写入数组时,另一个线程应该在项目可用时以正确的顺序读取它们,如何做到这一点?

UPD2

我正在添加测试程序来演示我想要实现的内容和方式.至少在我的机器上它恰好起作用.我rand用来告诉你我不能使用一般queue,我需要使用array-based结构:

#include "stdafx.h"
#include <string>
#include <boost/thread.hpp>
#include "windows.h" // for Sleep


const int BUFFER_LENGTH = 10;
int buffer[BUFFER_LENGTH];
short flags[BUFFER_LENGTH];

void ProcessorThread() {
    for (int i = 0; i < BUFFER_LENGTH; i++) {
        while (flags[i] == 0);
        printf("item %i received, value = %i\n", i, buffer[i]);
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    memset(flags, 0, sizeof(flags));
    boost::thread processor = boost::thread(&ProcessorThread);
    for (int i = 0; i < BUFFER_LENGTH * 10; i++) {
        int x = rand() % BUFFER_LENGTH;
        buffer[x] = x;
        flags[x] = 1;
        Sleep(100);
    }
    processor.join();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

item 0 received, value = 0
item 1 received, value = 1
item 2 received, value = 2
item 3 received, value = 3
item 4 received, value = 4
item 5 received, value = 5
item 6 received, value = 6
item 7 received, value = 7
item 8 received, value = 8
item 9 received, value = 9
Run Code Online (Sandbox Code Playgroud)

我的计划是否有效?您如何重新设计它,可能使用boost/stl中的一些现有结构而不是数组?是否有可能在不影响延迟的情况下摆脱"旋转"?

Max*_*kin 3

如果使用线程进入睡眠状态,则需要几微秒的时间才能唤醒。这是您无法避免的进程调度程序延迟,除非线程像您一样忙于旋转。该线程还需要是实时 FIFO 的,这样当它准备好运行但耗尽了它的时间量时,它就不会进入睡眠状态。

因此,没有任何替代方案可以匹配繁忙旋转的延迟。

(令人惊讶的是您使用的是 Windows,如果您认真对待高频交易,最好避免使用)。