繁体   English   中英

退出后从回调访问线程堆栈

[英]thread stack access from callback after exit

以下代码为某些清理操作注册了一个回调。 一旦请求停止,就会从main调用回调,线程退出。 然后回调等待几毫秒并访问线程堆栈上的vector ,这似乎无效,因为线程不再存在。

valgrindg++ -fsanitize=address没有报告任何问题并且size()的输出总是符合预期。 这让我想知道只要main中的request_stop没有返回,访问线程栈上的vector是否正确。

输出是:

thread finished 140037635319488
call back from: 140037639857984, size 1234
main finished 140037639857984

请注意,在线程完成其最后一行之后访问向量。

问题:这段代码是未定义的行为吗?

C++ 标准中的一些相关引用可能会有所帮助

#include <iostream>
#include <thread>
#include <vector>
#include <stop_token>
#include <chrono>

using namespace std::chrono_literals;

void thread_func(std::stop_token st)
{
    std::vector<int> v;

    std::stop_callback cb{st, [&v]
        {
            std::this_thread::sleep_for(1000ms);
            for (int i=0; i<1234; ++i)
                v.push_back(i);
            std::cout << "call back from: " << std::this_thread::get_id()
                      << ", size " << v.size() << '\n';
        }};

    while (!st.stop_requested())
    {
        // ...
    }
    std::cout << "thread finished " << std::this_thread::get_id() << '\n';
}

int main()
{
    std::stop_source src;
    auto t = src.get_token();

    auto thr = std::jthread{thread_func, t};
    std::this_thread::sleep_for(500ms);

    bool b = src.request_stop();

    std::cout << "main finished " << std::this_thread::get_id() << '\n';
}

如果回调是从另一个线程运行的(在您的情况下是request_stop()调用中的主线程),则std::stop_callback的析构函数会阻塞,直到该调用完成,然后才销毁存储的可调用对象。

因为你在cb之前声明了v ,所以当thread_func在停止请求之后返回时,只有在cb的析构函数在堆栈展开期间返回之后才会销毁向量。 线程仅在堆栈展开后退出。

暂无
暂无

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

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