Рассмотрим этот код (извлеченный из Simple-Web-Server, но знание библиотеки не должно быть необходимым, чтобы ответить на этот вопрос):Здесь нужны заграждения?
HttpServer server;
thread server_thread;
server.config.port = 8080;
server.default_resource["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
string content = "Hello world!"
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.size() << "\r\n\r\n" << content;
};
server_thread = thread([&server]() {
server.start();
});
HttpServer::default_resource
является станд :: unordered_map, который, в моем понимании, не является потокобезопасный. port
- неподписанный короткий.
Предполагая, что мое понимание C++ заборов памяти является правильным, server
, как видно по новой нити, не может быть в допустимом состоянии, как основной поток не мог бы написать изменения в port
и default_resource
память, доступной из других потоков , Таким образом, server.start()
может работать неправильно.
Чтобы это исправить, я бы изменить код, добавив к atomic_thread_fence
с:
HttpServer server;
thread server_thread;
server.config.port = 8080;
server.default_resource["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
string content = "Hello world!"
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.size() << "\r\n\r\n" << content;
};
atomic_thread_fence(memory_order_release);
server_thread = thread([&server]() {
atomic_thread_fence(memory_order_acquire);
server.start();
});
ли мое понимание правильно, и как atomic_thread_fence
s необходимо?
Все операции, выполняемые родительским потоком, упорядоченным до инициализации потока, должны быть завершены с точки зрения только что созданного потока. Поэтому в этом случае забор нити не требуется, поскольку сервер был инициализирован перед вызовом 'std :: thread :: thread()'. –
Кажется, что вы путаете фактический поток (концепция параллелизма) с объектом обработчика потока (объект C++). –