底层lambda线程安全时,多线程调用std::function<void(int)&>是否安全?
std::function::operator() 的线程安全性探讨
本文核心探讨的问题:当底层存储的lambda函数本身具备线程安全性时,是否可以从多个线程中调用std::function<void(int)>&类型的引用?
核心结论
可以安全调用,原因如下:
- 根据C++标准,
std::function的const成员函数是线程安全的,多个线程可同时调用而无需额外同步机制。std::function::operator()被声明为const成员函数,只要底层可调用对象的调用操作是线程安全的,对std::function的调用就是线程安全的。 - 示例中的lambda通过
std::mutex保证了共享变量count的线程安全访问,本身具备线程安全性;同时整个过程中std::function对象仅被初始化并放入队列,后续没有任何修改操作,不存在数据竞争的风险。
示例代码
void target(int i, std::deque<std::function<void(int)>>* queue) { std::function<void(int)>& f = queue->front(); f(i); } int main() { std::mutex mu; int count = 0; std::function<void(int)> f = [&](int i) { std::unique_lock<std::mutex> lock(mu); count += i; }; std::deque<std::function<void(int)>> queue; queue.push_back(std::move(f)); std::vector<std::thread> threads; for (int i = 0; i < 32; ++i) { threads.emplace_back(target, i, &queue); } for (std::thread& thread : threads) { thread.join(); } std::cout << count << std::endl; }
注意事项
如果有线程同时对std::function对象执行修改操作(如赋值、swap等非const成员函数),即使底层可调用对象线程安全,也会触发数据竞争,此时必须通过同步机制保护std::function对象的修改操作。
内容的提问来源于stack exchange,提问作者heiner
相关产品推荐
相关产品推荐

