2010-08-24 3 views
1

나는 boost :: thread를 시험해보기 위해 간단한 콘솔 애플리케이션을 작성했다. 나는 그런데 다중 스레드 초보자이다. N
6635.28 MS : T
6638.29 MS : 총
을 눌러 계속하려면 아무 키나 여기에 코드의 출력은 코드스레드 및 비 스레드 함수 호출의 실행 순서는 무엇입니까?

#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이다. . . 내가 1 호선과 2 호선 출력의 순서를 변경하면

은 그러나됩니다 :

6274.57 MS : T
6250.56 MS : N
12531.3 MS : 총
을 눌러 어떤 키를 계속하시오. . .

경우 1에서 bAvg.join()은 Avg가 실행 된 직후 및 완료되기 전에 시작됩니다. 나는 사건 1과 사건 2의 결과가 서로 반대라고 생각했다. 이 스레드의 실행 순서와 관련이 있습니다.

편집 :
실제로 나는 거래 목적으로 응용 프로그램을 작성할 계획입니다. 예를 들어 단일 주식에 대해 곧 나오는 신호 당 적어도 10 개의 계산 스레드를 생성하려고합니다. tcp 연결을 통해 신호가 수신됩니다. 주 실행 스레드가 다른 하위 스레드의 완료를 기다리는 경우 주 스레드가 유휴 상태이므로 단일 신호가 쉽게 누락 될 수 있습니다. 어떻게 신호를 처리하고 계산 스레드를 실행해야합니까?

+0

당신이 묻는 질문이 주어지면, 당신이 뒤로 물러나 정말로 스레딩에 머리를 쓰는 데 시간을 할애하는 것이 좋습니다.당신이 무슨 일이 일어나고 있는지 잘 이해하지 못한다면 벌레와 고통의 세계에 대한 포털입니다. 아마 거래 코드에서 그걸 원하지 않을 것입니다. 이제는 단일 스레드 응용 프로그램을 작성할 수 있습니까? 여러 스레드가 필요하다는 것을 입증 했습니까? 순진한 스레드 응용 프로그램은 통신 비용으로 인해 스레드되지 않은 응용 프로그램보다 느리게 끝납니다. –

+0

@chrispy : 사실 내 단일 스레드 applcation 준비되었습니다. 하지만 내 관심사는 수신 신호가 방금받은 신호를 수신하는 경우입니다. 대답은 내가 가진다면 다른 스레드를 열고 다른 CPU 코어에서 신호를 돌보는 것이다. 내 대답이 틀렸어? –

+0

당신에게 적합한 간단한 디자인 : 들어오는 신호를 처리하고 처리를 위해 하나의 스레드를 가지며, 대기열에서 꺼내어 순차적으로 처리하도록하는 하나의 스레드가 있습니다. 아마도 당신을 위해 큐잉 할 TCP 라이브러리를 얻을 수 있을까요? 즉 가능한 경우 신호를 처리 할 준비가 될 때까지 신호를 그대로 둡니다. 나는 당신의 TCP 라이브러리의 세부 사항을 모른다. 이렇게하면 스레딩 세부 정보가 차단됩니다. –

답변

2

두 함수가 모두 병렬로 실행되기 때문에 첫 번째 경우는 N T와 T N 일 수 있습니다. 두 번째 경우에는 첫 번째 기능 (T)이 두 번째 (N)이 시작되기 전에 끝나야하기 때문에 출력은 T N 일 수 있습니다. bAvg.join은 "스레드 함수가 종료 될 때까지 대기"를 의미합니다.

+0

"스레드 종료 대기 함수"가 실제로 의미합니까? 스레드가 강제 종료되면 스레드 기능이 실제로 종료됩니까? 이것은 변덕스러운 질문이 아니며, 나는 정말로 모른다. –

+0

Space_C0wb0y : 스레드 기능이 return 문을 실행하거나 중단 지점을 통해 부스트 스레드가 종료됩니다. 조인 연산자는 그 중 하나를 기다리고 기본 OS 스레드가 종료 될 때만 리턴합니다. –

1

줄 1과 줄 2가 바뀌면 먼저 다른 스레드에서 bAvg을 실행하고 끝날 때까지 기다리십시오. 그런 다음 주 스레드에서만 bAvg을 시작하십시오. 이 경우 총 시간이 두 배가됩니다. 계산은 순차적으로 수행됩니다.

+0

그래서 bAvg가 두 번 해고되었다고 말하는 겁니까? –

+0

@bahadir : 아니요.이 프로그램에는 두 개의 스레드 인 기본 실행 스레드와 'bAvg'가 있습니다. 첫 번째 경우 두 스레드가 병렬로 작업을 수행하는 반면, 두 번째 경우에는 주 스레드가 작업의 공유를 수행하기 전에'bAvg' 작업 완료를 기다립니다 ('join' 호출에서). –

0

boost::thread을 만들면 새 스레드가 즉시 시작되지만 이는 일반적으로 스레드 예약을 처리하는 OS가 즉시 해당 스레드로 전환한다는 의미는 아닙니다. 이것은 언제든지 발생할 수 있습니다.

boost::this_thread::yield() 

이 현재 스레드 (이 경우 주 스레드), 다른 스레드에 찬성 남아있는 CPU 시간을 산출하게, 같은 bAvg을 같은 : 예를 들어, 당신은 스레드를 만들 직후에이 줄을 instering 시도 (하지만 꼭 필요한 것은 아니며 OS 스케줄러까지).

기본적으로 동기화를 사용하지 않으면 다른 스레드 나 프로세스에서 실행 순서에 대해 어떠한 가정도하지 마십시오.