You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::move_only_function线程安全性:多线程调用与替换的合法性问询

线程中调用与替换std::move_only_function是否安全?

这种操作不安全,会触发未定义行为。

核心原因

C标准并未规定std::move_only_function的operator()(调用函数)和operator=(赋值新函数)是线程安全的操作。当一个线程调用fn(),另一个线程执行fn = []{}时,属于对同一对象的并发读写操作,构成了数据竞争。根据C标准,数据竞争会直接导致未定义行为——哪怕你不在意执行的是旧函数还是新函数,也可能出现程序崩溃、内部状态损坏等不可预测的问题。

你的代码中,两个异步线程分别对fn进行调用和赋值,没有任何同步机制,完全符合上述数据竞争的场景。

安全的实现方式

要避免数据竞争,需要用同步机制(比如互斥锁)保护对fn的所有访问:

#include <future>
#include <functional>
#include <mutex>

int main() {
    std::move_only_function<void()> fn = []{};
    std::mutex mtx;

    auto future1 = std::async(std::launch::async, [&]{ 
        std::lock_guard<std::mutex> lock(mtx);
        fn(); 
    });
    auto future2 = std::async(std::launch::async, [&]{ 
        std::lock_guard<std::mutex> lock(mtx);
        fn = []{}; 
    });

    future1.get();
    future2.get();
}

通过std::mutex和std::lock_guard,确保同一时间只有一个线程能访问fn,无论是调用还是赋值操作,从根本上避免了数据竞争。


内容的提问来源于stack exchange,提问作者Benjamin Buch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:42:04