Question regarding the value of PyThreadState.thread_id

Hi all. My apologies if this is a topic that's been discussed already, but I wasn't able to locate anything in the archive on the subject. I was wondering if there's a fundamental reason for using PyThread_get_thread_ident instead of PyThread_get_thread_native_id for the value of the thread_id field of the PyThreadState object. The reason why I'm asking is that I would like to have easy access to the native TID on Linux to identify the /proc/stat file associated with the thread from an external process. At the moment I have to resort to calling process_vm_readv to copy the struct pthread over to local VM and then guess where the tid field might be. So, if there's no fundamental reason for thread_id to be PyThread_get_thread_ident, I would like to propose to change it to PyThread_get_thread_native_id instead. Thanks, Gabriele -- "Egli è scritto in lingua matematica, e i caratteri son triangoli, cerchi, ed altre figure geometriche, senza i quali mezzi è impossibile a intenderne umanamente parola; senza questi è un aggirarsi vanamente per un oscuro laberinto." -- G. Galilei, Il saggiatore.

Hi, There are two reasons: * PyThread_get_thread_native_id() was only added recently (Python 3.8) * PyThread_get_thread_native_id() is not portable and not available on all platforms: the function is only declared if the PY_HAVE_THREAD_NATIVE_ID macro is defined. Maybe PyThreadState.thread_id could use PyThread_get_thread_native_id() if avaialble, or PyThread_get_thread_ident() otherwise. But that sounds like an incompatible change. Another approach would be to add a *new* structure member, like thread_native_id. It would not exist if the PY_HAVE_THREAD_NATIVE_ID macro is not defined. Include/pythread.h: #if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif thread_pthread.h implementation: unsigned long PyThread_get_thread_native_id(void) { if (!initialized) PyThread_init_thread(); #ifdef __APPLE__ uint64_t native_id; (void) pthread_threadid_np(NULL, &native_id); #elif defined(__linux__) pid_t native_id; native_id = syscall(SYS_gettid); #elif defined(__FreeBSD__) int native_id; native_id = pthread_getthreadid_np(); #elif defined(__OpenBSD__) pid_t native_id; native_id = getthrid(); #elif defined(_AIX) tid_t native_id; native_id = thread_self(); #elif defined(__NetBSD__) lwpid_t native_id; native_id = _lwp_self(); #endif return (unsigned long) native_id; } Victor -- Night gathers, and now my watch begins. It shall not end until my death. On Fri, Apr 16, 2021 at 10:47 PM Gabriele <phoenix1987@gmail.com> wrote:

Hi Victor Thanks for your reply. Indeed, upon further investigation, I have realised changing the value of thread_id is not wise as there are other methods that expect this field to be a pthread_t. I have opened issue https://bugs.python.org/issue43879https://bugs.python.org/issue43879 to have the new field added. I'm happy to do the work myself if it gets accepted. Cheers, Gabriele On Sat, 17 Apr 2021, 11:07 Victor Stinner, <vstinner@python.org> wrote:

Hi, There are two reasons: * PyThread_get_thread_native_id() was only added recently (Python 3.8) * PyThread_get_thread_native_id() is not portable and not available on all platforms: the function is only declared if the PY_HAVE_THREAD_NATIVE_ID macro is defined. Maybe PyThreadState.thread_id could use PyThread_get_thread_native_id() if avaialble, or PyThread_get_thread_ident() otherwise. But that sounds like an incompatible change. Another approach would be to add a *new* structure member, like thread_native_id. It would not exist if the PY_HAVE_THREAD_NATIVE_ID macro is not defined. Include/pythread.h: #if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif thread_pthread.h implementation: unsigned long PyThread_get_thread_native_id(void) { if (!initialized) PyThread_init_thread(); #ifdef __APPLE__ uint64_t native_id; (void) pthread_threadid_np(NULL, &native_id); #elif defined(__linux__) pid_t native_id; native_id = syscall(SYS_gettid); #elif defined(__FreeBSD__) int native_id; native_id = pthread_getthreadid_np(); #elif defined(__OpenBSD__) pid_t native_id; native_id = getthrid(); #elif defined(_AIX) tid_t native_id; native_id = thread_self(); #elif defined(__NetBSD__) lwpid_t native_id; native_id = _lwp_self(); #endif return (unsigned long) native_id; } Victor -- Night gathers, and now my watch begins. It shall not end until my death. On Fri, Apr 16, 2021 at 10:47 PM Gabriele <phoenix1987@gmail.com> wrote:

Hi Victor Thanks for your reply. Indeed, upon further investigation, I have realised changing the value of thread_id is not wise as there are other methods that expect this field to be a pthread_t. I have opened issue https://bugs.python.org/issue43879https://bugs.python.org/issue43879 to have the new field added. I'm happy to do the work myself if it gets accepted. Cheers, Gabriele On Sat, 17 Apr 2021, 11:07 Victor Stinner, <vstinner@python.org> wrote:
participants (2)
-
Gabriele
-
Victor Stinner