Как показывать сообщения в режиме реального времени во время пиковой громкости - PullRequest
0 голосов
/ 22 августа 2011

Я пытаюсь найти лучший способ отображения огромного количества сообщений в секунду. Я разработал следующую программу, которая генерирует случайные данные, которые имитируют поток, который должен отображаться в реальном времени без каких-либо изменений

Программа показывает 4 столбца: метки реального времени, метки времени данных, время задержки и идентификатор сообщения. Пример:
00: 00: 00.002000 00: 00: 00.000000 00: 00: 00.000000 # 1
00: 00: 00.592034 00: 00: 00.585000 00: 00: 00.585000 # 2
00: 00: 01.653095 00: 00: 01.642000 00: 00: 01.057000 # 3
00: 00: 01.692097 00: 00: 01.675000 00: 00: 00.033000 # 4
00: 00: 01.698097 00: 00: 01.675000 00: 00: 00.000000 # 5
00: 00: 01.698097 00: 00: 01.675000 00: 00: 00.000000 # 6
00: 00: 01.698097 00: 00: 01.675000 00: 00: 00.000000 # 7
00: 00: 01.698097 00: 00: 01.675000 00: 00: 00.000000 # 8
00: 00: 01.698097 00: 00: 01.675000 00: 00: 00.000000 # 9
00: 00: 01.698097 00: 00: 01.675000 00: 00: 00.000000 # 10
...

Например, строка # 4 была «получена» во второй 1.675, у нее была задержка в 0,033 секунды от строки # 3, и это сообщение фактически отображалось в 1.692097. Первый и второй столбцы должны быть как можно ближе. Тем не менее, таймеры расходятся, когда есть выборки данных. Во время работы программы вы можете заметить, как столбец 2 липкий, потому что сообщения, отображаемые в одну и ту же миллисекунду, рисуются построчно, а не отображаются все сразу. Я не знаю, является ли это аппаратным ограничением или плохой реализацией, но в конце тест показывает, как время первого столбца в несколько раз превышает время второго. Я знаю, что вычисления и отображение данных занимают некоторое время, но я думаю, что разница слишком велика. Как я могу сопоставить оба таймера? Если я не могу, как я могу сделать их как можно ближе?

Большое спасибо за потраченное время,

#include <iostream>
#include <string>
#include <sstream>
#include <list>
#include <time.h>

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread.hpp>

using namespace std;
using namespace boost::posix_time;

int main(int argc, char* argv[])
{
    srand (time(NULL));
    int rmil, num=0; //Integers for generating random milliseconds and counting messages 
    time_duration snapshot, sum = milliseconds(0); //Sum of total message delais and its holding value

    struct message
    {
        time_duration delay;
        string print;
    } m;

    list<message> mlist; //List of messages

    //Simulating 30 seconds of data with peaks of volume. 

    //The first message is at time 0
    m.delay = milliseconds(0); num++;
    m.print = to_simple_string(sum)+"  00:00:00.000000  #"+boost::lexical_cast<std::string>(num);
    mlist.push_back(m);

    while(sum<seconds(30)) //Generating 30 seconds of data
    {
        if(rand()%100<10) // Probability to have a peak data volume
        {
                snapshot = sum;
                while(sum<snapshot+seconds(1)) //Generating messages for 1 second
                {
                    rmil = rand() % 100; //0.050 second delay between packs of messages
                    int mpm = rand() % 150; //Num of Message per millisecond

                    m.delay = milliseconds(rmil);
                    num++; sum += milliseconds(rmil);
                    m.print = to_simple_string(sum)+"  "+to_simple_string(m.delay)+"  #"+boost::lexical_cast<std::string>(num);
                    mlist.push_back(m); 
                    for(int n=0;n<mpm;n++) //Adding messages at the same millisecond
                    {
                        m.delay = milliseconds(0); num++;
                        m.print = to_simple_string(sum)+"  00:00:00.000000  #"+boost::lexical_cast<std::string>(num);
                        mlist.push_back(m); //Push message to the list
                    }
                }
        }
        else
        {
            rmil = rand() % 2000; //1 second delay (average) between messages, no peak volume
            m.delay = milliseconds(rmil); 
            num++; sum += milliseconds(rmil);
            m.print = to_simple_string(sum)+"  "+to_simple_string(m.delay)+"  #"+boost::lexical_cast<std::string>(num);
            mlist.push_back(m);
        }
    }

    //Displaying messages with delay
    list<message>::iterator it = mlist.begin();

    stringstream scrmsg;
    ptime ltime = microsec_clock::local_time(); //Record the local time
    while(it!=mlist.end())
    {
        if((*it).delay > boost::posix_time::milliseconds(0)) 
        {
            boost::this_thread::sleep((*it).delay); 
            cout << to_simple_string(microsec_clock::local_time()-ltime) << "  " <<(*it).print << endl;
            it++;
        }
        else //Group the messages at the same millisecond
        {
            while((*it).delay == boost::posix_time::milliseconds(0))
            {
                scrmsg << to_simple_string(microsec_clock::local_time()-ltime) << "  " << (*it).print << endl;
                it++;
            }
            cout << scrmsg.str();
            scrmsg.str("");
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 22 августа 2011

Вы, вероятно, смотрите на квант потока.Даже если планировщик решит немедленно возобновить работу вашего потока, ему все равно придется приостановить его, чтобы решить это, и он может решить вместо этого запустить другие потоки.Не было бы способа заставить вашу программу работать с такой точностью.Это особенно верно, поскольку консольный ввод-вывод блокирует, что будет просто отбрасывать ваше время.

0 голосов
/ 22 августа 2011

Вы не можете сопоставить таймеры.

Не существует надежного способа определения времени вызовов функций в одну и ту же миллисекунду. Вашей операционной системе может потребоваться приостановить выполнение вашей программы, чтобы выполнять вызовы с более высоким приоритетом (в данном случае, например, консольный вывод).

...