2012-07-18 132 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