通知另一个线程数据可用的最快方法是什么?有什么替代方法可以纺吗? [英] what is the fastest way to notify another thread that data is available? any alternativies to spinning?

查看:62
本文介绍了通知另一个线程数据可用的最快方法是什么?有什么替代方法可以纺吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

One my thread writes data to circular-buffer and another thread need to process this data ASAP. I was thinking to write such simple spin. Pseudo-code!

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

以上,我使用a表示存储在b中的数据可用于处理.也许我也应该为这种热"过程设置线程亲和力.当然,这种旋转在CPU方面非常昂贵,但是对我来说还可以,因为我的主要要求是等待时间.

Above I'm using a to indicate that data stored in b is available for processing. Probaly I should also set thread afinity for such "hot" process. Of course such spin is very expensive in terms of CPU but it's OK for me as my primary requirement is latency.

问题是-我应该写这样的东西吗?或者booststl允许以下内容:

The question is - am I should really write something like that or boost or stl allows something that:

  1. 易于使用.
  2. 大致相同(甚至更好?)延迟,同时占用更少的CPU资源?
  1. Easier to use.
  2. Has roughly the same (or even better?) latency at the same time occupying less CPU resources?

我认为我的模式太笼统了,应该在某个地方实现一些良好的实现.

I think that my pattern is so general that there should be some good implementation somewhere.

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

upd It seems my question is still too complicated. Let's just consider the case when i need to write some items to array in arbitrary order and another thread should read them in right order as items are available, how to do that?

upd2

我正在添加测试程序以演示我要达到的目标和方式.至少在我的机器上它可以正常工作.我正在使用rand向您显示我不能使用常规的queue,而我需要使用array-based结构:

I'm adding test program to demonstrate what and how I want to achive. At least on my machine it happens to work. I'm using rand to show you that I can not use general queue and I need to use array-based structure:

#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;
}

输出:

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

我的程序是否可以正常运行?您将如何重新设计它,可能使用boost/stl中的某些现有结构而不是数组?是否可以摆脱旋转"而不影响延迟?

Is my program guaranteed to work? How would you redesign it, probably using some of existent structures from boost/stl instead of array? Is it possible to get rid of "spin" without affecting latency?

推荐答案

如果使用方线程进入睡眠状态,则唤醒它需要几微秒的时间.这是您无法避免的进程调度程序延迟,除非线程像您一样忙于纺纱.该线程还需要是实时FIFO,以便它在准备运行时永远不会进入睡眠状态,但会耗尽其时间量.

If the consuming thread is put to sleep it takes a few microseconds for it to wake up. This is the process scheduler latency you cannot avoid unless the thread is busy-spinning as you do. The thread also needs to be real-time FIFO so that it is never put to sleep when it is ready to run but exhausted its time quantum.

因此,没有其他方法可以匹配繁忙旋转的延迟.

So, there is no alternative that could match latency of busy spinning.

(让您感到惊讶的是,您正在使用Windows,如果您认真对待HFT,最好避免使用它.)

(Surprising you are using Windows, it is best avoided if you are serious about HFT).

这篇关于通知另一个线程数据可用的最快方法是什么?有什么替代方法可以纺吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆