C++计时器:暂停程序执行直到完成

3

C ++,XCode 4.6.3,OSX 10.8.2,在iOS上部署

我正在尝试创建一个定时事件。

我的思路是创建一个线程,在其中进行计时,然后在结束时调用另一个函数。这可以工作,但会暂停程序的其余部分。

//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;
}

有没有一种不会暂停程序执行的方法来做到这一点?

更新:

我可以在头文件中声明线程,并在stop_thread()中加入线程:

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

但会抛出以下错误:

'std::thread'类型不提供调用运算符

更新2:调用t1.detach()代替join似乎可以正常工作。


1
不要调用join函数,至少在你完成了想要在这20秒内做的任何事情之前不要调用。join会阻塞你的主线程。 - Igor Tandetnik
让我困惑的是,我可以将 std::thread t1 移动到头文件中,并将 ti.join() 放在 stop_thread() 中,但这会使我面临 t1(start_thread); 的问题,因为它会抛出一个关于未提供函数调用的错误。 - Jasmine
虽然调用detach()能够让结果不必回到主线程,仅仅触发某个事件即可,但这种方式仍然可行。 - Jasmine
2个回答

1

你说得对,它可以工作: 这是来自cpp参考的一个例子 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));
}

输出:

开始线程调用者。

开始并发线程。

退出线程调用者。

退出并发线程。

我们可以看到,如果没有调用detach,那么并发线程会在线程调用者结束后才能结束。这是不可能的。

希望这有所帮助,但Jason找到了解决方案。


0

使用类(class)代替。

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;
    }
};

似乎调用 detach() 也是有效的。我喜欢这个类方法。 - Jasmine
我唯一看不到的是如何告诉线程它已经停止。在构造时,mStatePAUSEDrun() 中的 while 循环将一直运行,直到 mState == STOPPED,所以我猜在 20 秒后调用 stop。 - Jasmine
@Jason 我没有注意到...现在已经修复了。 - gifnoc-gkp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接