简体   繁体   English

使用Builder(Borland库)的C ++ Worker线程

[英]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. 我有一个应用程序,它基本上有一个GUI和一个负责运行我的主程序和对象创建的函数。

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. 目前我的GUI会崩溃,因为当后台工作完成后会有太多的后台工作,它会再次恢复生机。

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. 我需要创建一个工作线程(我们不需要一个接口线程,因为我的GUI只显示正在发生的事情的进展。),工作线程将运行我的函数,另一个工作线程将运行我的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. Threadz与C ++ Builder很相似,尤其是。 if you do not need any GUI comms. 如果您不需要任何GUI通信。 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:) 关于GUI通信的问题,我不得不问一些建议 - 需要一个宏来处理消息,我提供了错误的表单类 - 我有一个堆栈溢出:)

There is a TThread class in 'classes', similar to Delphi. “类”中有一个TThread类,类似于Delphi。 Override 'Execute' to get execution for your thread code, eg: 覆盖'Execute'以获取线程代码的执行,例如:

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. 如果你没有TThread类,(我有C ++ Builder 2009 - 之前不确定),你可以按照@inkooboo的建议回退API调用。 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. WINAPI CreateThread()只调用简单的C风格函数或静态方法,因此您通常需要显式传递一个实例(通常是'this')作为CreateThread参数,以便从线程代码中调用实例方法。 ThreadPool example using CreateThread API, (though I'm sure that if you have STL, you will have TThread as well): ThreadPool示例使用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

You can use WinAPI threading facilities or any threading library such as: boost / C++11 threading library , pthread , any other. 您可以使用WinAPI线程工具或任何线程库,例如: boost / C ++ 11线程库pthread ,任何其他。

Welcome to multithreading in C++ ! 欢迎使用C ++进行多线程处理!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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