当 pthread 启动时,它是否需要互斥锁来访问之前在生成它的线程中写入的全局数据

When a pthread starts does it need a mutex to access global data written previously in the thread that spawned it

本文关键字:线程 数据 全局 是否 启动 pthread 访问      更新时间:2023-10-16

我在Linux上有一个带有两个线程的c ++程序线程 A 将一些数据写入 std::map不会将其他数据写入此地图然后线程 A 创建线程 B线程 B 从映射中读取数据

那么在这种情况下我需要使用互斥体吗?

如果没有,那么在哪里指定此保证。

No.线程创建是一个同步点,因此在创建第二个线程之前第一个线程产生的所有效果将在创建第二个线程时"发生"(以标准语言可以精确的方式)。

更准确地说,在一个线程创建并随后加入另一个线程的上下文中......

  • 线程创建之前的所有内容 - 在线程函数内的任何内容之前,以及
  • 线程
  • 函数中的所有内容都发生在线程连接之后的任何内容之前。

不,仅当您要同时从两个或多个线程读取/写入内存时,才需要互斥锁。由于当您有多个线程时,您的 std::map 是不可变的,因此您不需要任何同步。您永远不需要在不可变数据上使用互斥锁。即使在你的情况下,线程 B 会写入 std::map,仍然只有一个线程会同时在这个内存上 r/w,你不需要同步一个线程。

事实上,只要有可能,主导模式应该是:

(可变)数据随任务移动

因此,数据归使用它的线程所有。现在,它不需要"物理"迁移,但使用移动语义使图片更加清晰:

#include <map>
#include <string>
using namespace std;
using Map = map<string, int>;
Map worker(Map&& data)
{
    for (auto& el : data)
        el.second *= -1;
    return std::move(data);
}
#include <cassert>
#include <iostream>
#include <future>
int main()
{
    Map global
            { { "one", 1 },
              { "two", 2 },
              { "three", 3 } };
    auto background = async(worker, std::move(global));
    assert(global.empty());    // data now owned by the worker thread!
    global = background.get(); // await the result from the worker
    for (auto const& el: global) // now the data is owned by the main thread
        std::cout << el.first << ": " << el.second << "n";
}

请注意main中间的assert:甚至不可能并发访问。

科利鲁上观看直播。