Denis Sheremet
Denis Sheremet

Reputation: 2583

How do I get sequential thread ids

I've got a c++ linux project composed of separate producer and consumer executables. Producer has multiple threads, and each thread has a different shared memory area to be used for interprocess communication. Threads are started by a third-party library and I can't easily pass custom parameters to them.

My problem is what I need a way to setup threads to write to different areas of shared memory to avoid races and locks.

So far I came up with the following solution:

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

and then inside the producer

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

But this solution feels like total overkill for such a simple task.

I can't just use stuff like syscall(SYS_gettid) % NUMBER_OF_THREADS because there's no guarantee thread id's would be sequential.

Are there an easy way of doing this?

Upvotes: 2

Views: 488

Answers (2)

John Bollinger
John Bollinger

Reputation: 180201

Are there an easy way of doing this?

Instead of having a central registry of sequential thread numbers, how about simply having a central generator for sequential thread numbers? Each thread gets its number (once), and stores it somewhere under its control. And you can implement that with a simple atomic integer:

static std::atomic_uint next_thread_number(0);

Each thread can then just do ...

unsigned int my_thread_number = next_thread_number++;

... since the ++ operator of std::atomic performs an atomic read-modify-write operation.

Upvotes: 1

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136256

Are there an easy way of doing this?

There is no API or requirement for process/thread ids to be generated in a certain way.

You should use a hash table (e.g. std::unordered_map) to map a pid_t or tid_t to a number from a specific range.

Upvotes: 0

Related Questions