带有赋值运算符和调用运算符的 std::function 并发

Posted

技术标签:

【中文标题】带有赋值运算符和调用运算符的 std::function 并发【英文标题】:std::function concurrency with assignment operator and call operator 【发布时间】:2019-10-14 17:00:58 【问题描述】:

std::function::operator=std::function::operator() 可以同时调用吗?

线程一上执行std::function::operator=而在线程二上执行std::function::operator()是未定义的行为吗?

我假设这可能是一个原子操作,我们不能在调用哪个函数之间进行中间操作。我不关心哪个运行,只是我们没有处于某种无效状态。

【问题讨论】:

如果你改写这个问题,我希望答案变得显而易见。诸如“我可以在分配新功能的同时执行功能吗?”或者也许“我可以在用程序 y 替换它的同时运行程序 x 吗?” "[res.on.objects]/1 如果从不同线程调用标准库函数可能会引入数据竞争,则程序的行为是不确定的。条件下这可能发生在 20.5.5.9 中。 [注意:修改在线程之间共享的标准库类型的对象有未定义行为的风险,除非该类型的对象被明确指定为可共享而没有数据争用或用户提供锁定机制。——尾注]" @IgorTandetnik 我能得到这个答案吗? 如果 std::function 包含一个 lambda,则重新分配 std::function 将在旧 lambda 仍在执行时释放它。即使它不包含 lambda,在 operator() 试图决定要做什么时分配它也会导致混乱(在旧对象上调用新分配的成员函数,或调用部分分配的函数指针) . @RaymondChen 这个事实很有趣。如果我使用绑定会是真的吗? 【参考方案1】:

"[res.on.objects]/1 如果调用 来自不同线程的标准库函数可能会引入数据 种族。可能发生这种情况的条件在 20.5.5.9。 [注意:修改线程之间共享的标准库类型的对象有未定义的行为风险,除非对象 该类型被明确指定为可以在没有数据的情况下共享 比赛或用户提供锁定机制。 ——尾注]"——

评论人:伊戈尔·坦德尼克

话虽如此,我找到了一种解决方法来做我想做的事。可以在呼叫运算符中进行分配。这意味着我不需要在不同的线程上进行分配。

【讨论】:

以上是关于带有赋值运算符和调用运算符的 std::function 并发的主要内容,如果未能解决你的问题,请参考以下文章

带有模板类的赋值运算符 - 没有可接受的转换,C++

使用带有 unique_ptr 向量的赋值运算符

C++ 拷贝构造函数和赋值运算符

派生赋值运算符从基础调用

C++:在派生类构造函数中调用基类赋值运算符的错误形式?

复制构造函数与赋值运算符(=)有何不同