如何获取顺序线程 ID

How do I get sequential thread ids

我有一个由单独的生产者和消费者可执行文件组成的 c++ linux 项目。 Producer有多个线程,每个线程都有不同的共享内存区用于进程间通信。线程是由第三方库启动的,我不能轻易地向它们传递自定义参数。

我的问题是我需要一种方法来设置线程以写入共享内存的不同区域以避免竞争和锁定。

到目前为止,我想出了以下解决方案:

static size_t get_thread_index() {
    static std::mutex once;
    std::lock_guard<std::mutex> guard(once);

    static std::map<pid_t, size_t> id_map;

    pid_t tid = syscall(SYS_gettid);

    auto it = id_map.find(tid);

    if (it != id_map.end()) {
        return it->second;
    } else {
        assert(id_map.size() < SHM_QUEUE_MAX_NODES);
        return (id_map[tid] = id_map.size());
    }
}

然后在生产者内部

static thread_local size_t node_id = get_thread_index();
(*shm_q)[write_node_id] ...

但是对于这样一个简单的任务,这个解决方案感觉有点矫枉过正。

我不能只使用 syscall(SYS_gettid) % NUMBER_OF_THREADS 之类的东西,因为不能保证线程 ID 是连续的。

有没有简单的方法来做到这一点?

Are there an easy way of doing this?

没有 API 或要求 process/thread 以某种方式生成 ID。

您应该使用散列 table(例如 std::unordered_map)将 pid_ttid_t 映射到特定范围内的数字。

Are there an easy way of doing this?

与其拥有连续线程号的中央 注册表,不如简单地拥有连续线程号的中央 生成器 怎么样?每个线程获得它的编号(一次),并将它存储在它控制的某个地方。你可以用一个简单的原子整数来实现它:

static std::atomic_uint next_thread_number(0);

然后每个线程都可以做...

unsigned int my_thread_number = next_thread_number++;

... 因为 std::atomic++ 运算符执行原子读-修改-写操作。