简体   繁体   中英

C++ Worker threads with Builder (Borland Libraries)

I have an application that basically has a GUI and a function that is responsible for running my main program and the creation of objects.

Currently my GUI will crash as there is too much background work going on when the background work is complete it will come back to life again.

I need to create a worker thread (we do not need an interface thread as my GUI only shows progress of what is happening.), the worker thread will run my function and the other worker thread will run my GUI.

Im struggling to find any information on this. Google does not seem to be helping, could any one point me to some useful information? At the moment I have something like this:

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

Threadz is ezy with C++ Builder, esp. if you do not need any GUI comms. I had to ask advice on SO about an issue with GUI comms - a macro is needed to handle the messages and I had supplied the wrong form class - I got a stack overflow:)

There is a TThread class in 'classes', similar to Delphi. Override 'Execute' to get execution for your thread code, eg:

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

If you have no TThread class, (I have C++ Builder 2009 - not sure about earlier), you can fall back on API calls as suggested by @inkooboo. WINAPI CreateThread() will only call a straightforward C-style function or a static method, so you usually need to explicitly pass an instance, ('this' usually), as the CreateThread parameter in order to call instance methods from the thread code. ThreadPool example using CreateThread API, (though I'm sure that if you have STL, you will have TThread as well):

#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

You can use WinAPI threading facilities or any threading library such as: boost / C++11 threading library , pthread , any other.

Welcome to multithreading in C++ !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM