Reputation: 2583
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
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
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