How do I get a thread ID from an arbitrary pthread_t?
Since pthread
s do not need to be implemented with Linux threads (or kernel threads at all, for that matter), and some implementations are entirely user-level or mixed, the pthread
s interface does not provide functions to access these implementation details, as those would not be portable (even across pthread
s implementations on Linux). Thread libraries that use those could provide this as an extension, but there do not seem to be any that do.
Other than accessing internal data structures of the threading library (which you understandably do not want, although with your assumptions about processor affinity and Linux thread IDs, your code will not be portable anyway), you may be able to play a trick at creation time, if you control the code that creates the threads:
Give pthread_create()
an entry function that calls gettid()
(which by the way you are likely to have to do using the syscall
macro directly because it is not always exported by libc
), stores the result somewhere, and then calls the original entry function. If you have multiple threads with the same entry function, you can pass an incremented pointer into an array in the arg
argument to pthread_create
, which will then be passed to the entry function you created to store the thread ID in. Store the pthread_t
return value of pthread_create
in the same order, and then you will be able to look up the Linux thread IDs of all threads you created given their pthread_t
value.
Whether this trick is worth it, depends on how important setting the CPU affinity is in your case, versus not accessing internal structures of the thread library or depending on a thread library that provides pthread_setaffinity_np
.
get pthread_t from thread id
I don't think such a function exists but I would be happy to be corrected.
As a workaround I can create a table mapping &pthread_t
to pid_t
and ensure that I always invoke pthread_create()
via a wrapper that adds an entry to this table. This works very well and allows me to convert an OS thread id to a pthread_t
which I can then terminate using pthread_cancel()
. Here is a snippet of the mechanism:
typedef void* (*threadFunc)(void*);
static void* start_thread(void* arg)
{
threadFunc threadRoutine = routine_to_start;
record_thread_start(pthread_self(),syscall(SYS_gettid));
routine_to_start = NULL; //let creating thread know its safe to continue
return threadRoutine(arg);
}
How to get thread id of a pthread in linux c program?
pthread_self()
function will give the thread id of current thread.
pthread_t pthread_self(void);
The pthread_self()
function returns the Pthread handle of the calling thread. The pthread_self() function does NOT return the integral thread of the calling thread. You must use pthread_getthreadid_np()
to return an integral identifier for the thread.
NOTE:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
is significantly faster than these calls, but provides the same behavior.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
Does Posix thread ID have an one-to-one relation with linux thread ID?
Does Posix thread ID have an one-to-one relation with linux thread ID
Yes.
But consider this an implementation detail. Other OSs might do this differently.
which is usually defined as
pthread_t
is opaque. As well do not make any assumptions on how it is implemented.
I found that one linux thread ID maps to several POSIX thread IDs
Really? I doubt this. At least not if all POSIX thread Ids in question were valid, that is the related thread either had not been joined yet or, if running detached, the thread had not ended yet.
How to map pthread_t to pid (on Linux)
One (convoluted, non-portable, Linux-specific, lightly destructive) method of mapping pthread_t
to tid
without looking into struct pthread
is as follows:
- Use
pthread_setname_np
to set a thread name to something unique. - Iterate over subdirectories of
/proc/self/task
and read a line from a file namedcomm
in each of those. - If the line equals to the unique string just used, extract
tid
from the last component of the subdirectory name. This is your answer.
The thread name is not used by the OS for anything, so it should be safe to change it. Nevertheless you probably want to set it back to the value it had originally (use pthread_getname_np
to obtain it).
How to extract taskid(tid) of a pthread from the parent thread?
All threads have a unique id:std::thread::id this_id = std::this_thread::get_id();
You can store it in a variable when the program starts and it'll be accessible from the other threads.
I understand what you mean when you say parent thread, but even though one thread gave birth to another, they are siblings.
if you want the master thread to be able to get the /proc
path to each worker thread, you could wrap the worker thread object in a class that, when it starts the actual thread, creates a path property that the master can later get.
An example:
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
// A base class for thread object wrappers
class abstract_thread {
public:
abstract_thread() {}
abstract_thread(const abstract_thread&) = delete;
abstract_thread(abstract_thread&& rhs) :
m_th(std::move(rhs.m_th)), m_terminated(rhs.m_terminated), m_cv{}, m_mtx{} {}
abstract_thread& operator=(const abstract_thread&) = delete;
abstract_thread& operator=(abstract_thread&& rhs) {
terminate();
join();
m_th = std::move(rhs.m_th);
m_terminated = rhs.m_terminated;
return *this;
}
virtual ~abstract_thread() {
// make sure we don't destroy a running thread object
terminate();
join();
}
virtual void start() {
if(joinable())
throw std::runtime_error("thread already running");
else {
std::unique_lock<std::mutex> lock(m_mtx);
m_terminated = true;
// start thread and wait for it to signal that setup has been done
m_th = std::thread(&abstract_thread::proxy, this);
m_cv.wait(lock, [this] { return m_terminated == false; });
}
}
inline bool joinable() const { return m_th.joinable(); }
inline void join() {
if(joinable()) {
m_th.join();
}
}
inline void terminate() { m_terminated = true; }
inline bool terminated() const { return m_terminated; }
protected:
// override if thread specific setup needs to be done before start() returns
virtual void setup_in_thread() {}
// must be overridden in derived classes
virtual void execute() = 0;
private:
std::thread m_th{};
bool m_terminated{};
std::condition_variable m_cv{};
std::mutex m_mtx{};
void proxy() {
{
std::unique_lock<std::mutex> lock(m_mtx);
setup_in_thread(); // call setup function
m_terminated = false;
m_cv.notify_one();
}
execute(); // run thread code
}
};
// an abstract thread wrapper capable of returning its /proc path
class proc_path_thread : public abstract_thread {
public:
// function to call from master to get the path
const std::string& get_proc_path() const { return m_proc_path; }
protected:
void setup_in_thread() override {
m_proc_path =
std::move(std::string("/proc/")) + std::to_string(syscall(SYS_gettid));
}
private:
std::string m_proc_path{};
};
// two different thread wrapper classes. Just inherit proc_path_thread and implement
// "execute()". Loop until terminated() is true (or you're done with the work)
class AutoStartThread : public proc_path_thread {
public:
AutoStartThread() { start(); }
private:
void execute() override {
while(!terminated()) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << std::this_thread::get_id() << " AutoStartThread running\n";
}
}
};
class ManualStartThread : public proc_path_thread {
void execute() override {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << std::this_thread::get_id() << " ManualStartThread running\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
};
int main() {
AutoStartThread a;
std::cout << a.get_proc_path() << "\t// AutoStartThread, will have path\n";
ManualStartThread b;
std::cout << b.get_proc_path()
<< "\t// ManualStartThread not started, no path\n";
b.start();
std::cout << b.get_proc_path()
<< "\t// ManualStartThread will now have a path\n";
b.join();
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
// terminate() + join() is called automatically when abstract_thread descendants
// goes out of scope:
//
// a.terminate();
// a.join();
}
Possible output:
/proc/38207 // AutoStartThread, will have path
// ManualStartThread not started, no path
/proc/38208 // ManualStartThread will now have a path
139642064209664 ManualStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
C: Printing out multiple threads' ID's before they execute anything?
One simple way to implement a thread pool with each thread having an opportunity to do preparatory work, before all threads will start actual work, is to have an additional startup mutex, associated condition variable, and a counter for ready threads:
static pthread_mutex_t prep_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t prep_cond = PTHREAD_COND_INITIALIZER;
static volatile size_t prep_count = 0;
static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static volatile size_t thread_count = 0;
static inline pid_t gettid(void) { return syscall(SYS_gettid); }
static void *thread_function(void *idref)
{
/* Get the number/index of this thread. */
const size_t num = *(pid_t *)idref;
const pid_t tid = gettid();
/* Replace it with the Linux tid. */
*(pid_t *)idref = tid;
/* Block here until preparatory work can be done. */
pthread_mutex_lock(&prep_mutex);
printf("Thread %zu of %zu has started.\n", id + 1, thread_count);
fflush(stdout);
prep_count++;
pthread_cond_signal(&prep_cond);
pthread_mutex_unlock(&prep_mutex);
/* Block until actual work can start. */
pthread_mutex_lock(&thread_mutex);
...
When creating the thread pool, the creator holds both mutexes. When it is ready to let the threads start the prep work, it releases the prep_mutex
, waiting on the prep_cond
until sufficient number of threads have completed preparatory work (prep_count
is high enough). Then, it releases the thread_mutex
.
int start_threads(size_t max_count)
{
pthread_t thread_id[max_count];
pid_t linux_tid[max_count];
pthread_attr_t attrs;
int err = 0;
/* Assume no threads currently running */
prep_count = thread_count = 0;
/* Shrink stack size; the default is too large. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 2*PTHREAD_STACK_MIN);
/* Grab the mutexes, so the threads will block initially. */
pthread_mutex_lock(&prep_mutex);
pthread_mutex_lock(&thread_mutex);
while (thread_count < max_count) {
linux_tid[thread_count] = thread_count;
err = pthread_create(thread_id + thread_count, &attrs,
thread_function, linux_tid + thread_count);
if (err)
break;
thread_count++;
}
/* Attributes are no longer needed. */
pthread_attr_destroy(&attrs);
/* No threads created at all? */
if (thread_count < 1) {
pthread_mutex_unlock(&prep_mutex);
pthread_mutex_unlock(&thread_mutex);
/* Return failure. */
return err;
}
/* All threads have now been created; let them do prep work. */
while (prep_count < thread_count) {
pthread_cond_wait(&prep_cond, &prep_mutex);
}
pthread_mutex_unlock(&prep_mutex);
/* All threads have finished their prep work; start working. */
pthread_mutex_unlock(&thread_mutex);
...
The above creates up to max_num
threads, with their pthread IDs in thread_id[]
, and their Linux tids in linux_tid[]
.
When the thread starts, it gets a pointer to the location to store the Linux tid to. Initially, that contains the index of the thread ("thread number", starting at 0), so thread_function
grabs that as num
, obtains the Linux tid as tid
, and stores it to the location given as a parameter. This way, both the original thread and the created thread know the index (num
), pthread ID (thread_id[]
, pthread_self()
), and Linux tid (linux_tid[]
and tid
).
Note how the arrays are dereferenced in the pthread_create()
call. If array
is an array, and index
is an index to it, then &(array[index]) == array + index
.
Above, the start_threads()
function does not assume it can start all max_num
threads. It does return with nonzero errno
number if it cannot create any, but if it can create at least one thread, as soon as the threads can grab prep_mutex
, the thread_count
will reflect the correct number of threads in their gang. (There is no reason to fail just because you were only able to create 53 worker threads instead of 54, say.)
Related Topics
Why Sigint Can Stop Bash in Terminal But Not via Kill -Int
Unix Command to Convert Xls File into Xlsx File
How to Get Notified of Modification in The Memory in Linux
Problems with Sudo Inside Expect Script
Get Man Pages for Driver Functions
Grep Array Parameter of Excluded Files
Which Is Faster of Two Case or If
Oracle Query - Ora-01652: Unable to Extend Temp Segment But Only in Some Versions of Sql*Plus
Linux: How to Send a Whole Packet to a Specific Port on Another Host
Find String and Replace Line in Linux
Pipe Sox Play Command to Stdout
Ftrace: Only Print Output of Trace_Printk()
How to Include Cutil.H in Linux
Difference Between ./Executable and . Executable
Can Not Add New User in Docker Container with Mounted /Etc/Passwd and /Etc/Shadow
Linux >2.6.33: Could Sendfile() Be Used to Implement a Faster 'Cat'
How to Find Out The User of Parent Shell Inside a Child Shell
Is There Any Reference Implementation of Linux File System Filter Driver