简体   繁体   中英

C++ Timer pausing execution of program until finished

C++, XCode 4.6.3, OSX 10.8.2, deploying on iOS

I am trying to create a timed event.

My thought process was to create a thread, do the timing in it and then at the end have it call another function. This is working however it is pausing the rest of the program.

//Launch a thread
std::thread t1(start_thread);

//Join the thread with the main thread
t1.join();

void start_thread()
{
    std::cout << "thread started" << std::endl;

    auto start = std::chrono::high_resolution_clock::now();

    std::this_thread::sleep_until(start + std::chrono::seconds(20));

    stop_thread();
}

void stop_thread()
{
    std::cout << "thread stopped." << std::endl;
}

Is there a way to do this that doesn't pause program execution?

Update:

I could declare the thread in the header file and join in the stop_thread():

void stop_thread()
{
    std::cout << "thread stopped." << std::endl;
    ti.join();
}

but that throws:

Type 'std::thread' does not provide a call operator

UPDATE 2: Calling t1.detach() instead of join seems to work.

You're right it works: Here is an example coming from cpp reference http://en.cppreference.com/w/cpp/thread/thread/detach

#include <iostream>
#include <chrono>
#include <thread>

void independentThread() 
{
    std::cout << "Starting concurrent thread.\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Exiting concurrent thread.\n";
}

void threadCaller() 
{
    std::cout << "Starting thread caller.\n";
    std::thread t(independentThread);
    t.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Exiting thread caller.\n";
}

int main() 
{
    threadCaller();
    std::this_thread::sleep_for(std::chrono::seconds(5));
}

Output: Starting thread caller. Starting concurrent thread. Exiting thread caller. Exiting concurrent thread.

We see that the concurrent thread ends after the thread caller ends. This is not possible if detach is not called.

Hope that helps, but Jason found the solution.

Use a class instead.

enum{ PAUSED, STARTED, STOPPED };

class AsyncEvent
{
protected:
    unsigned char mState;

public:
    AsyncEvent():mState(PAUSED){ mThread = std::thread(&AsyncEvent::run,this); }
    ~AsyncEvent(){ mThread.join(); }

private:
    std::thread mThread;

    void run()
    {
        std::cout << "thread started" << std::endl;

        while(mState != STOPPED)
        {
            if(mState == PAUSED)break;

            auto start = std::chrono::high_resolution_clock::now();
            std::this_thread::sleep_until(start + std::chrono::seconds(20));
        }
    }

    void stop()
    {
        mState = STOPPED;
    }

    void pause()
    {
        mState = PAUSED;
    }
};

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