Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Process.myTid() VS Thread.currentThread().getId()

I have simple Activity that calls AsyncTask, so I print some id's regarding Proces and Thread:

From onCreate android.os.Process.myUid(): 10137
From onCreate android.os.Process.myPid(): 29776
From onCreate android.os.Process.myTid(): 29776
From onCreate Thread.currentThread().getId(): 1
/****************************************************************/
From Async doInBackground android.os.Process.myUid(): 10137
From Async doInBackground android.os.Process.myPid(): 29776
From Async doInBackground android.os.Process.myTid(): 30426
From Async doInBackground Thread.currentThread().getId(): 12556
  1. Uid is same because its app-specific sandbox
  2. Similar with Pid: Each app is one Process
  3. 3rd line in onCreate same as Pid because it's the UIThread and in Android OS as based on Linux we know that issue regarding Process is actually Thread etc... And in the Async the ThreadId is different because AsyncTask runs on different Thread rather then the UIThread

The thing I'm struggling to understand is Thread.currentThread().getId(). What I expect is to get same id as Thread.currentThread().getId() for the same execution environment. e.g. for onCreate I want lines 3,4 to be same (29776), and for Async I expect lines 3,4 to be the same (30426). What is going on here?

Thanks,

like image 666
michael Avatar asked Oct 16 '15 13:10

michael


1 Answers

Very interesting question by the OP and I decided to dig (love open source).

The short answer is: they're different because they're different, because they were never meant to be the same.

  • Process.myTid() is the linux thread ID
  • Thread.getId() is a simple sequential long number.

But the short answer is boring, so let's explore where the answer comes from (links in the answer points to the relevant source codes).

In Process.myTid(), you'll see that is simply calls from Os.gettid() that in itself calls a native method on Libcore for that method is below:

public static int gettid() { return Libcore.os.gettid(); }

furthermore the docs for Os.gettid(); you'll find a link to Linux Programmer's Manual

gettid() returns the caller's thread ID (TID). In a single-threaded process, the thread ID is equal to the process ID (PID, as returned by getpid(2)). In a multithreaded process, all threads have the same PID, but each one has a unique TID.

  • That means, Process.myTid() returns the thread ID as given by the Linux kernel.

On the other hand Thread.getId() is simply returning a long. This long is assigned during init(...) as tid = nextThreadId();. Then the last piece of this puzzle, below is the code for nextThreadId()

/* For generating thread ID */
private static long threadSeqNumber;

private static synchronized long More ...nextThreadID() {
    return ++threadSeqNumber;
}
  • That means, Thread.getId() is simply a "java layer" static long being auto-increment for each thread.
like image 78
Budius Avatar answered Sep 28 '22 08:09

Budius