2009-05-15 2 views
0

새 스레드에서 "실행"함수를 호출하려고합니다. 지금 당장은 새로운 스레드에서 "실행"을 실제로 실행하지 않는 openMP를 사용하여이 코드를 작성했습니다. 참고 : OpenMP를 사용하여 도움을 요청하지 않습니다. 이 코드는 단지 빠른 수정이었습니다. 나는 이것에 대해가는 CreateThread() 메서드를 선호 할 것이다.상속을 사용한 다중 스레딩 (C++)

vector<ICommand*>* commands; 
string strInput; 
// For each command... 
for(vector<ICommand*>::iterator i = commands->begin(); i != commands->end(); ++i) 
{ 
    // ...if the current command we're examining is valid... 
    if((*i)->ContainsCommand(strInput)) 
    { 
     // ...run it in a new thread and don't let ZChatInput handle it normally... 
     #pragma omp sections nowait 
     { 
     #pragma omp section 
      (*i)->Run(strInput); 
     #pragma omp section 
      bRet = false; 
     } 

     // ...and don't check any more commands. 
     break; 
    } 

} 

표준 및 STL을 사용하면 어떻게됩니까? 물론, 나는 작동하는 방법을 찾고 있어요 :)

답변

0

그래서 MSDN 설명서를 다시 확인한 후에 알아 냈습니다. 당신이 관심이있는 경우에 대비하여 내가 한 일은 다음과 같습니다.

static vector<ICommand*>* commands; 
// This is what we pass to CommandOnThread. 
struct CommandParameter 
{ 
    string strInput; 
    ICommand* command; 
}; 

int CommandOnThread(CommandParameter* cp) 
{ 
    cp->command->Run(cp->strInput); 
    delete cp; 

    return 0; 
} 

void foo() 
{ 
    string strInput; 
    ... 
    // For each command... 
    for(vector<ICommand*>::iterator i = commands->begin(); i != commands->end(); ++i) 
    { 
     // ...if the current command we're examining is valid... 
     if((*i)->ContainsCommand(strInput)) 
     { 
      // Put the CP on the stack. 
      CommandParameter* temp = new CommandParameter; 
      if(temp == NULL) 
      { 
       Print("Out of memory!"); 
       bRet = false; 
       break; 
      } 

      // ...set up the parameters to createthread... 
      temp->strInput = strInput; 
      temp->command = *i; 

      // ...run it in a new thread... 
      CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CommandOnThread, temp, NULL, NULL); 

      // ...and don't check any more commands. 
      bRet = false; 
      break; 
     } 
    } 
} 
3

Boost.Thread를 사용하는 것은 어떻습니까?

if((*i)->ContainsCommand(strInput)) 
{ 
    boost::thread t(boost::bind(&ICommand::Run, *i)); 
} 

이것은 분리 된 스레드에서 "실행"됩니다. (참고로이 테스트를 수행하지 않았습니다.)

+0

아니요, 죄송합니다. 제 3 자 라이브러리에서 부끄러워하려고합니다. 이 기능이 VS2010에있는 경우 사용해 보겠습니다. 그러나 그때까지, 아직도 내가 찾고있는 것이 아닙니다. 또한 strInput을 매개 변수로 전달하는 것을 잊었습니다. –

+2

부스트 문제는 무엇입니까? 거의 stl처럼 표준입니다. 부스트 라이브러리가 새로운 표준으로 옮겨 가고 있습니다. 부스트 스레드가 새로운 표준이되면 인상적이지 않을 것입니다. (스레드에 대한 새로운 표준이 있다는 것을 알고 있지만, 스레드가 비슷할 지 모르겠습니다. 모델) –

+0

C++ 0x에는 boost.thread와 유사한 스레딩 기능이 있습니다. http://en.wikipedia.org/wiki/C%2B%2B0x#Threading_facilities –

1

각 명령에 대해 실제로 스레드를 만드시겠습니까? 스레드 생성은 비용이 많이 듭니다. 이 부분이 비동기 적으로 필요한 경우 - 동기화 된 대기열을 만들려면 사전에 생성 된 스레드 수 (즉, 여기에 확장 성이 있음)로 대기열에서 차단 한 다음 루프의 대기열에 메시지 (포인터?)를 넣으십시오. .

 
// setup 
sync_queue wq; // that would be protected by mutex and a conditional var or two 
for (i = 0; i < parallel_factor; ++i) start_thread(th_func, wq); 
... 

// your loop body : 
    ... 
    if (valid_input) q.put(item); 
    ... 

// thread function 
void th_func(sync_queue& q) 
{ 
    work_item* pwi; 
    while ((pwi = q.get())) do_it(pwi); 
} 

말이 :

의견을 응답?

+0

각 명령에 대한 스레드를 만들지 않습니다. 입력이 유효하고 더 이상 입력이없는 경우에만 스레드를 생성합니다. 그렇지 않으면 정말 비참하게 느려지므로 비동기 적이어야합니다. 구현 전략을 이해할 수 없습니다. 예제 코드를 보여줄 수 있습니까? –

+0

그렇습니다.하지만 간단한 스레드 생성을위한 많은 작업처럼 보입니다 ... CreateThread 또는 다른 WinAPI를 사용하면 더 좋은 방법이 될 것입니다. –

+0

유효한 모든 입력에 대해 Run()을 호출합니까? 그런 다음 스레드가 미리 시작되도록하십시오. 그렇지 않으면 싱글 스레드보다 느리다는 것을 알 수 있습니다. 그리고 예, 스레드를 망친 것은 많은 작업입니다. –

2

이 마음에 드십니까? 전화를 먼저 명령 개체에 입력을 저장하고 : 조금 두 단계에서 명령 입력을 전달하는 명령 인터페이스를 변경해야이 들어

vector<ICommand*>* commands; 
string strInput; 

void CommandOnThread(void* command) 
{ 
    (ICommand*)command->Run(); 
} 

// For each command... 
for(vector<ICommand*>::iterator i = commands->begin(); i != commands->end(); ++i) 
{ 
    // ...if the current command we're examining is valid... 
    if((*i)->ContainsCommand(strInput)) 
    { 
     //Attach the input to the command 
     (*i)->AttachInput(strInput); 
     _beginthread(CommandOnThread, 0, *i); 
     break; 
    } 
} 

: http://msdn.microsoft.com/en-us/library/kdzttdcb(VS.80).aspx

당신이 뭔가를
+0

내가 제공 한 코드의 컨텍스트에서 나를 보여줄 수 있습니까? boost 예제와 비슷한 –

+0

과 같이 함수에 대한 포인터를 매개 변수로 사용하면 위로 이동합니다. _beginthread 및 CreateThread는 멀티 스레딩을위한 MS 함수입니다. – DaClown

+0

int h = (HANDLE) _beginthreadex (NULL, 0, (* i) -> 실행, & strInput, 0, NULL); 정확히 알 수는 없지만 Run은 _stdcall 함수 여야합니다. 이것은 win32 API입니다 – ryansstack

2

시도 할 수 있습니다 인자없이 Run(). 당신이 비슷하다면 _beginthread를 CreateThread로 대체 할 수 있습니다.

명백히하기 : _beginthread (또는 CreateThread)의 함수 매개 변수로 인스턴스 메소드를 사용할 수 없습니다. 위의 솔루션은 함수에 객체 (명령)를 전달한 다음 인스턴스 메소드 (실행)를 호출하는 것입니다. 그러나이 경우 스레드 함수에 추가 인수를 전달할 수 없으므로 인수를 인스턴스 메서드에 전달할 수 없습니다. 이것에 대한 가장 쉬운 해결책은 스레드 함수에 인수를 전달하기 전에 인수를 인스턴스에 연결하는 것입니다.

이 정보가 도움이되기를 바랍니다. 물론 Command 클래스의 인터페이스와 구현을 변경할 수없는 경우에는이 솔루션을 사용할 수 없습니다.

+0

"AttachInput"은 어디에 정의되어 있습니까? 또한 명령 -> 실행()에 매개 변수를 전달하지 않습니다. –

+0

직접 정의해야합니다. 하나의 인수 만 스레드 함수에 전달할 수 있으며 이미 명령 오브젝트 전달에 사용됩니다. –