views:

71

answers:

3

hello,

i have written a simple console application just to try boost::thread, i am a multithreading newbie by the way. here is the code

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

the output of that code is

6621.1 ms : N
6635.28 ms : T
6638.29 ms : Total
Press any key to continue . . .

But when i change the order of line 1 and line 2 the output becomes:

6274.57 ms : T
6250.56 ms : N
12531.3 ms : Total
Press any key to continue . . .

in case 1, bAvg.join() is fired just after Avg fired and before it is finished. i thought the results of case 1 and case 2 would be the opposite of each other. this has something to do with the execution order of threads i think.

edit:
actually i am planning to write an application for trading purposes. i am going to create, say, at least 10 threads of calculations per upcoming signal for a single stock. the signals will be received via tcp connection. but if the main execution thread waits for the completion of other sub-threads', then a single signal may be easily missed, because the main thread is idle. how am i supposed to handle the signals and run the calculation threads?

+2  A: 

In the first case, order may be both N T and T N, because both functions are executed in parallel. In the second case, output can be only T N, because the first function (T) must finish before the second (N) starts. bAvg.join means "Wait for thread function to exit".

Alex Farber
@Alex Farber: Does it really mean "Wait for thread function to exit"? If the thread is terminated forcefully, does the thread-function actually exit? This is not a rethorical question, I really don't know.
Space_C0wb0y
Space_C0wb0y: boost thread ends when thread function executes return statement, or through interruption point. join operator waits for any of them, and returns only when underlying OS thread ends.
Alex Farber
+1  A: 

When line 1 and line 2 are exchanged, you first fire bAvg in another thread and wait for it to finish. Then only you start bAvg on the main thread. This is why in that case the total time is doubled: your calculations are done sequentially.

Didier Trosset
so you are saying bAvg is fired twice?
bahadir
@bahadir: No, the program has two threads, the main execution thread and `bAvg`. In the first case both threads are performing work in parallel, while in the second case you make the main thread wait (in the `join` call) for the completion of `bAvg` work before performing it's share of the job.
David Rodríguez - dribeas
A: 

When you create a boost::thread, a new thread is started immediately, but that doesn't mean that the OS, which usually handles the scheduling of threads, immediately switches to that thread. This may happen at any time. For instance, try instering this line right after you create the thread:

boost::this_thread::yield()

This makes the current thread (your main thread in this case), yield its remaining CPU-time in favor of other threads, such as bAvg (but not neccessarily, its all up to the OS-scheduler).

As a rule, unless you use synchronization, never make any assumption about the order of execution in different threads or processes.

Space_C0wb0y