The process has an ID, can be obtained through getpid (), and the thread has an ID, but GLIBC does not provide encapsulation. You need to make a system call yourself. In the critical path, the system call or performance has an impact. So we can think of a cache wrapper like glibc to Getpid, which caches each thread's ID in thread local, and each thread actually initiates a system call only when it first calls Gettid.
#include <stdio.h><syscall.h><unistd.h>pid_t gettid () { Static __thread pid_t cached_tid; if 0 ) { = syscall (sys_gettid); } return Cached_tid;}
This code works fine until the fork is encountered. In my opinion, fork is a single-threaded era thing, incompatible with multithreading, so we rarely use the code. In fact, this problem is strange in addition to the thread that calls fork, because when fork, other threads will not be fork. But for the main thread or the single-threaded process, the problem is still there, the existence of uncomfortable.
Perhaps you can think of using pthread_atfork to do this, and the prototype is like this.
int pthread_atfork ( Void (*prepare) ( void Void (*parent) (void void (*child) (void));
The document says that the child will be called in the sub-process. But here is a problem, Cached_tid is a thread local variable, each line thread address is not the same, and the child function does not support the address, we have to use the dynamic Generation Code (thunk) of the wretched way?
It doesn't have to be that complicated, although glibc caches the getpid, but the fork getpid is going to change, so we can compare the PID changes every time we call it:
pid_t Gettid () { static __thread pid_t cached_pid; Static __thread pid_t cached_tid; = getpid (); if 0 ) { = = pid ; = Syscall (sys_gettid); } return Cached_tid;}
Getpid is efficient, so this code is also a university.
Check glibc source code, Getpid is from the current thread control block read, in fact, inside also wired path ID, but glibc but reluctant to provide encapsulation, let me think of a sentence, programmers why bother programmers.
Test:
int main () {printf ( " parent:pid=%d, tid=%d\n " Span style= "color: #000000;" >, Getpid (), Gettid ()); if (fork () = = 0 child:pid=%d, Tid=%d\n else {printf ( " parent after fork:pid=%d, tid=%d\n "
parent:pid=10776, tid=10776
Parent after fork:pid=10776, tid=10776
child:pid=10777, tid=10777
Behave as expected.
Gettid Efficient implementation of fork safety