2012-07-18 133 views
0

我有一個應用程序,基本上有一個GUI和一個負責運行我的主程序和創建對象的函數。C++工作線程與Builder(Borland庫)

目前我的圖形用戶界面會崩潰,因爲後臺工作完成後會有太多的後臺工作,它會再次恢復生機。

我需要創建一個工作線程(我們不需要接口線程,因爲我的GUI只顯示正在發生的事情的進展),工作線程將運行我的函數,另一個工作線程將運行我的GUI。

我正努力尋找這方面的任何信息。谷歌似乎沒有幫助,任何人都可以指向我一些有用的信息?目前,我有這樣的事情:

void __fastcall TfrmRunning::FormCreate(TObject *Sender) 
{ 
    //Does most of my background stuff when this form is created 
} 
+0

我認爲這是不鼓勵在C++ Builder的使用FORMCREATE(),從我還記得什麼,它與Delphi保持一定的兼容性。您應該在窗體的構造函數或FormShow事件中創建線程。 – Lundin 2012-09-24 12:55:29

回答

2

Threadz與C++ Builder,特別是ezy。如果你不需要任何GUI通信。我必須諮詢SO關於GUI通信的問題 - 需要一個宏來處理這些消息,並且我提供了錯誤的表單類 - 我得到了堆棧溢出:)

'類中有一個TThread類',類似於Delphi。覆蓋「執行」來獲得執行你的線程代碼,如:

class TpoolThread : public TThread{ 
    CBthreadPool *FmyPool; 
protected: 
    virtual void __fastcall Execute(void); 
public: 
    TpoolThread(CBthreadPool *myPool):TThread(true){ 
     FmyPool=myPool; 
     Resume(); 
    }; 
}; 

如果你沒有的TThread類,(我有C++ Builder的2009 - 不知道更早的版本),你可以依靠的API調用的建議由@inkooboo。 WINAPI CreateThread()只會調用一個簡單的C風格函數或靜態方法,因此您通常需要顯式傳遞一個實例(通常爲'this')作爲CreateThread參數,以便從線程代碼調用實例方法。使用的CreateThread API,(雖然我敢肯定,如果你有STL,你將有TThread類以及)線程池例如:

#ifndef cthreadpoolH 
#define cthreadpoolH 

#include <Classes.hpp> 
#include <deque.h> 

class ThreadPool; 

class PoolTask { 
friend class ThreadPool; 
    TNotifyEvent FonComplete; 
protected: 
    ThreadPool *myPool; 
    int param; 
public: 
    PoolTask(int inParam, TNotifyEvent OnDone):param(inParam),FonComplete(OnDone){}; 
    virtual void run()=0; 
}; 

template <typename T> class PCSqueue{ 
    CRITICAL_SECTION access; 
    deque<T> *objectQueue; 
    HANDLE queueSema; 
public: 
    PCSqueue(){ 
     objectQueue=new deque<T>; 
     InitializeCriticalSection(&access); 
     queueSema=CreateSemaphore(NULL,0,MAXINT,NULL); 
    }; 
    void push(T ref){ 
     EnterCriticalSection(&access); 
     objectQueue->push_front(ref); 
     LeaveCriticalSection(&access); 
     ReleaseSemaphore(queueSema,1,NULL); 
    }; 
    bool pop(T *ref,DWORD timeout){ 
     if (WAIT_OBJECT_0==WaitForSingleObject(queueSema,timeout)) { 
      EnterCriticalSection(&access); 
      *ref=objectQueue->back(); 
      objectQueue->pop_back(); 
      LeaveCriticalSection(&access); 
      return(true); 
     } 
     else 
      return(false); 
    }; 
}; 

class ThreadPool { 
    int FthreadCount; 
    PCSqueue<PoolTask*> queue; 
public: 
    ThreadPool(int initThreads){ 
     for(FthreadCount=0;FthreadCount!=initThreads;FthreadCount++){ 
      CreateThread(NULL,0,staticThreadRun,this,0,0); 
     }; 
    } 
    void setThreadCount(int newCount){ 
     while(FthreadCount<newCount){ 
      CreateThread(NULL,0,staticThreadRun,this,0,0); 
      FthreadCount++; 
     }; 
     while(FthreadCount>newCount){ 
      queue.push((PoolTask*)NULL); 
      FthreadCount--; 
     }; 
    } 
    static DWORD _stdcall staticThreadRun(void *param){ 
     ThreadPool *myPool=(ThreadPool*)param; 
     PoolTask *thisTask; 
     SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_BELOW_NORMAL); 
     while (myPool->queue.pop(&thisTask,INFINITE)){ 
      if(thisTask==NULL){return(0);}; 
      thisTask->run(); 
      if (thisTask->FonComplete!=NULL) { 
       thisTask->FonComplete((TObject*)thisTask); 
      } 
     } 
    } 
    void submit(PoolTask *aTask){ 
     aTask->myPool=this; 
     queue.push(aTask); 
    }; 
}; 

#endif