Are memory fences required here?

眉间皱痕 提交于 2019-12-13 16:39:38

问题


Consider this code (extracted from Simple-Web-Server, but knowledge of the library shouldn't be necessary to answer this question):

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 is a std::unordered_map, which, to my understanding, isn't thread-safe. port is an unsigned short.

Assuming my understanding of C++ memory fences is correct, server, as seen by the new thread, might not be in a valid state as the main thread might not have written the changes to port and default_resource to memory accessible from other threads. As such, server.start() might not work properly.

To fix this, I would have to change the code by adding to atomic_thread_fences:

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();
});

Is my understanding correct, and are both the atomic_thread_fences necessary?


回答1:


30.3.1.2 thread constructors

template <class F, class ...Args> 
explicit thread(F&& f, Args&&... args);

Synchronization: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.

In other words: when the thread function gets invoked, it is synchronized with everything that happened in the parent thread up until std::thread gets constructed, in the parent thread.

No explicit memory barriers/fences, of this kind, are needed.



来源:https://stackoverflow.com/questions/41427305/are-memory-fences-required-here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!