我写了一个简单的控制台应用程序只是为了尝试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连接接收。但是如果主执行线程等待其他子线程的完成,则可能很容易错过单个信号,因为主线程处于空闲状态。我该如何处理信号并运行计算线程?
答案 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调度程序)
通常,除非您使用同步,否则不要对不同线程或进程中的执行顺序做出任何假设。