Is it safe to call a std::function<void(int)>&
from several threads, provided the underlying lambda is thread-safe?
For instance (Godbolt link):
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;
}
The operator ()
of std::function
is marked as const
. See https://en.cppreference.com/w/cpp/utility/functional/function/operator() therefore calling it from multiple threads is thread-safe as it causes no changes to the std::function
. The lambda function that the std::function
wraps modifies an external variable guarded by a mutex so it is thread-safe too.
Thus the operations are thread-safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With