Gettid Efficient implementation of fork safety

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.