Using a boost thread: Signal and wait for terminat

2019-05-21 00:19发布

问题:

i'm currently writing a c/c++ dll for later use mostly in Delphi and i'm more familiar with threads in Delphi than c/c++ and especially boost. So i wonder how i can achieve the following scenario?

class CMyClass
{
    private:
        boost::thread* doStuffThread;
    protected:
        void doStuffExecute(void)
        {
            while(!isTerminationSignal()) // loop until termination signal
            {
                // do stuff
            }

            setTerminated(); // thread is finished
        };
    public:
        CMyClass(void)
        {
            // create thread
            this->doStuffThread = new boost::thread(boost::bind(&CMyClass::doStuffExecute, this));
        };

        ~CMyClass(void)
        {
            // finish the thread
            signalThreadTermination();
            waitForThreadFinish();

            delete this->doStuffThread;

            // do other cleanup
        };
}

I have red countless articles about boost threading, signals and mutexes but i don't get it, maybe because it's friday ;) or is it not doable how i think to do it?

Regards Daniel

回答1:

Just use an atomic boolean to tell the thread to stop:

class CMyClass
{
private:
    boost::thread doStuffThread;
    boost::atomic<bool> stop;
protected:
    void doStuffExecute()
    {
        while(!stop) // loop until termination signal
        {
            // do stuff
        }

        // thread is finished
    };
public:
    CMyClass() : stop(false)
    {
        // create thread
        doStuffThread = boost::thread(&CMyClass::doStuffExecute, this);
    };

    ~CMyClass()
    {
        // finish the thread
        stop = true;
        doStuffThread.join();

        // do other cleanup
    };
}

To wait for the thread to finish you just join it, that will block until it is finished and can be joined. You need to join the thread anyway before you can destroy it, or it will terminate your program.

There is no need to use a pointer and create the thread with new, just use a boost::thread object directly. Creating everything on the heap is wasteful, unsafe and poor style.

There is no need to use boost::bind to pass arguments to the thread constructor. For many many years boost::thread has supported passing multiple arguments to its constructor directly and it does the binding internally.

It's important that stop has been initialized to false before the new thread is created, otherwise if the new thread is spawned very quickly it could check the value of stop before it is initialized, and might happen to read a true value from the uninitialized memory, and then it would never enter the loop.

On the subject of style, writing foo(void) is considered by many C++ programmers to be a disgusting abomination. If you want to say your function takes no arguments then just write foo().