I'm looking at this snippet from seastar tutorial:
#include <seastar/core/coroutines.hh>
#include <seastar/coroutine/parallel_for_each.hh>
seastar::future<bool> all_exist(std::vector<sstring> filenames) {
bool res = true;
co_await seastar::coroutine::parallel_for_each(filenames, [&res] (const seastar::sstring& name) -> seastar::future<> {
res &= co_await seastar::file_exists(name);
});
co_return res;
}
I'm learning advanced C++, I suspect there is a race in this code. The &=
operator is in fact two operations, read and write, and it's not atomic. The lambda captures res
by reference and multiple threads modify it in parallel. This scenario can happen:
- both threads
A
andB
readtrue
fromres
- thread
A
writesfalse
- thread
B
, not seeing the write byA
, overwrites it back totrue
Is the above scenario possible? If not, why not?
The
seastar::coroutine::parallel_for_each
method, according to documentation, processes all elements in a single shard (i.e., a single thread). So no synchronization is necessary.The parallelism comes from executing using coroutines - multiple
file_exists
calls are initiated and wait for their return values in parallel, but the return values are processed by a single thread.The name is a bit confusing, elsewhere "parallel" means "multiple threads", e.g. here or here.