каков порядок выполнения многопоточного и непоточного вызова функции? - PullRequest
1 голос
/ 24 августа 2010

Я написал простое консольное приложение просто для того, чтобы попробовать boost :: thread, я, кстати, многопоточный новичок.здесь код

#include <iostream>
#include <boost/thread/thread.hpp>
#include <windows.h>

using namespace std;

void Avg(double * Src, double *Dst, int Per, int Len, string& s )
{
    LARGE_INTEGER s1,s2,f;
    QueryPerformanceFrequency(&f);
    QueryPerformanceCounter(&s1);
    for(int i = Per-1; i < Len ; i++)
    {
        double a = 0;
        for(int j = i; j > i-Per ; j--)
            a += Src[j];
        Dst[i] = a / Per;
    }       
    QueryPerformanceCounter(&s2);
   cout << double(s2.QuadPart-s1.QuadPart)/f.QuadPart*1000 << " ms : "+s << endl;
}

int main(int argc, char* argv[])
{
    int L = 200000;
    double  * a = new double[L], *b = new double[L] , *c = new double[L];
    for(int i =0; i < L;i++)
    {
        a[i] = i+2;
    }
    int x = 10000;
    boost::thread bAvg(Avg,a,b,x,L,string("T"));
    LARGE_INTEGER s1,s2,f;
    QueryPerformanceFrequency(&f);
    QueryPerformanceCounter(&s1);

    Avg(a,c,x,L,string("N")); // line 1
    bAvg.join(); // line 2

    QueryPerformanceCounter(&s2);
    cout << double(s2.QuadPart-s1.QuadPart)/f.QuadPart*1000 << " ms : Total" << endl;


    delete []a;
    delete []b;
    delete []c;

    system("PAUSE");
         return 0;
}

выход этого кода:

6621,1 мс: N
6635,28 мс: T
6638,29 мс: всего
Нажмителюбой ключ, чтобы продолжить.,.

Но когда я изменяю порядок строки 1 и строки 2, на выходе получается:

6274,57 мс: T
6250,56 мс: N
12531,3мс: всего
Нажмите любую клавишу для продолжения.,.

в случае 1, bAvg.join () запускается сразу после запуска Avg и до его завершения.я думал, что результаты случая 1 и случая 2 будут противоположны друг другу.я думаю, это как-то связано с порядком выполнения потоков.

edit:
На самом деле я планирую написать заявку для торговых целей.я собираюсь создать, скажем, по крайней мере 10 потоков вычислений для каждого предстоящего сигнала для одной акции.сигналы будут получены через TCP-соединение.но если основной поток выполнения ожидает завершения других подпотоков ', то единственный сигнал может быть легко пропущен, поскольку основной поток простаивает.как я должен обрабатывать сигналы и запускать вычисления?

Ответы [ 3 ]

2 голосов
/ 24 августа 2010

В первом случае порядок может быть как N T, так и T N, поскольку обе функции выполняются параллельно. Во втором случае выход может быть только T N, потому что первая функция (T) должна завершиться до начала второй (N). bAvg.join означает «Ожидание завершения функции потока».

1 голос
/ 24 августа 2010

При обмене строк 1 и 2 вы сначала запускаете bAvg в другом потоке и ждете его завершения. Тогда только вы начнете bAvg в главном потоке. Вот почему в этом случае общее время удваивается: ваши вычисления выполняются последовательно.

0 голосов
/ 24 августа 2010

Когда вы создаете boost::thread, новый поток запускается немедленно, но это не означает, что ОС, которая обычно обрабатывает планирование потоков, немедленно переключается на этот поток. Это может произойти в любое время. Например, попробуйте ввести эту строку сразу после создания потока:

boost::this_thread::yield()

Это делает текущий поток (ваш основной поток в данном случае) возвращает оставшееся время процессора в пользу других потоков, например bAvg (но не обязательно, все зависит от планировщика ОС). 1006 *

Как правило, если вы не используете синхронизацию, никогда не делайте предположений о порядке выполнения в разных потоках или процессах.

...