这里需要记忆围栏吗?

时间:2017-01-02 12:58:05

标签: c++ multithreading memory-barriers

考虑这段代码(摘自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是一个std :: unordered_map,根据我的理解,它不是线程安全的。 port是一张无符号的短片。

假设我对C ++内存防护的理解是正确的,server,如新线程所见,可能不会处于有效状态,因为主线程可能没有将更改写入portdefault_resource可以从其他线程访问内存。因此,server.start()可能无法正常运行。

要解决此问题,我必须通过添加到atomic_thread_fence s:

来更改代码
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是必要的吗?

1 个答案:

答案 0 :(得分:6)

  

30.3.1.2线程构造函数

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

同步:完成构造函数的调用   与调用f

副本的开始同步

换句话说:当线程函数被调用时,它会与父线程中发生的所有内容同步,直到在父线程中构造std::thread

不需要这种明确的记忆障碍/围栏。