线程和非线程函数调用的执行顺序是什么?

时间:2010-08-24 07:22:03

标签: c++ multithreading boost execution

我写了一个简单的控制台应用程序只是为了尝试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 ms:N
  6635.28 ms:T
  6638.29 ms:总计
  按任意键继续 。 。

但是当我改变第1行和第2行的顺序时,输出变为:

  

6274.57 ms:T
  6250.56 ms:N
  12531.3 ms:总计
  按任意键继续 。 。

在情况1中,bAvg.join()在Avg触发后和完成之前触发。我认为案例1和案例2的结果将是彼此相反的。这与我认为的线程的执行顺序有关。

修改
实际上我打算为交易目的编写一份申请。我打算为每个单一股票的即将到来的信号创建至少10个计算线程。信号将通过tcp连接接收。但是如果主执行线程等待其他子线程的完成,则可能很容易错过单个信号,因为主线程处于空闲状态。我该如何处理信号并运行计算线程?

3 个答案:

答案 0 :(得分:2)

在第一种情况下,顺序可以是N T和T N,因为两个函数并行执行。在第二种情况下,输出只能是T N,因为第一个函数(T)必须在第二个(N)开始之前完成。 bAvg.join表示“等待线程函数退出”。

答案 1 :(得分:1)

当交换第1行和第2行时,首先在另一个线程中触发bAvg并等待它完成。然后只有你在主线程上启动bAvg。这就是为什么在这种情况下总时间加倍:您的计算是按顺序完成的。

答案 2 :(得分:0)

当您创建boost::thread时,会立即启动新线程,但这并不意味着通常处理线程调度的操作系统会立即切换到该线程。这可能随时发生。例如,尝试在创建线程后立即修改此行:

boost::this_thread::yield()

这使得当前线程(在这种情况下是你的主线程)产生剩余的CPU时间,而不是其他线程,例如bAvg(但不是必须的,它完全取决于OS调度程序)

通常,除非您使用同步,否则不要对不同线程或进程中的执行顺序做出任何假设。