【问题标题】:Spawn thread and do something else while it's running for as long as it's active生成线程并在它运行时执行其他操作,只要它处于活动状态
【发布时间】:2020-03-09 16:30:09
【问题描述】:

我在下面有一个简单的程序,其中一些长时间运行的进程 someFn 工作,设置状态,工作设置状态,工作并设置状态。

someFn 正在运行时,我希望主线程查询它为someFn 的生命周期设置的状态。

显然这段代码是不正确的,因为T 在它真正加入之前是joinable,并且这个程序不会停止。

如何正确地让主线程在 T 的生命周期内循环,并在 T 终止后立即停止循环?

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

int STATE = 0;
static std::mutex mtx;

void setState(int newState) {
    std::lock_guard<std::mutex> lg(mtx);
    STATE = newState;
}

int getState() {
    std::lock_guard<std::mutex> lg(mtx);
    return STATE;
}


void someFn() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    setState(0);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    setState(1);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    setState(2);
}

int main()
{

    std::thread T(someFn);

    while (T.joinable()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        std::cout << getState() << std::endl;
    }

    T.join();

    return 0;

}

谢谢!

【问题讨论】:

  • while( getState() != 2) ?!?我想我不明白这个问题
  • 当然在这个特定的例子中有效,但让我们假设我不知道最终状态是什么。我只想知道T 何时终止。
  • 线程必须以某种方式发出信号,表明它已完成其工作。如果您不知道state 的最终值,请使用一些bool taskDone 作为std::atomic&lt;bool&gt; 或受互斥体保护
  • 听起来你可能正在寻找std::future

标签: c++ multithreading stdthread


【解决方案1】:

只有std::thread 你不能。

但您可以轻松制作自己的信号。例如:

#include <atomic>
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>

int STATE = 0;
static std::mutex mtx;

void setState(int newState) {
    std::lock_guard<std::mutex> lg(mtx);
    STATE = newState;
}

int getState() {
    std::lock_guard<std::mutex> lg(mtx);
    return STATE;
}

void someFn(std::atomic<bool>& isDone) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    setState(0);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    setState(1);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    setState(2);
    isDone.store(true);
}

int main() {
    std::atomic<bool> isDone{false};
    std::thread T(someFn, std::ref(isDone));

    while(!isDone.load()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        std::cout << getState() << std::endl;
    }

    T.join();

    return 0;
}

std::atomic 不需要互斥锁或其他同步,因为它已经是线程安全的。

【讨论】:

  • std::atomic for STATE 或许可以稍微简化一下。
  • 您需要将isDone 参数包装成std::ref。否则,由于 std::thread 的构造函数所做的隐式参数复制,您会收到错误。
  • @uneven_mark 我正在编辑它,而你评论我注意到了。 :-)
猜你喜欢
  • 2012-11-26
  • 2015-05-08
  • 1970-01-01
  • 2011-07-26
  • 2020-07-04
  • 2016-06-18
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
相关资源
最近更新 更多