Why is there no system call to create threads when I create multiple threads in java?

The following code creates 100 new java threads and starts them.

class ThreadTest { public static void main(String[] args) { for (int i = 0; i < 100; i++) { final int tNo = i; new Thread(new Runnable() { @Override public void run() { System.out.println("thread #" + tNo); } }).start(); } } } 

When I run the above code and record system calls made with strace, I cannot find the system call (possibly clone ()) that creates a new thread.

But when I check the threads for the above process with the ps -eLf command, then it lists (> 100) threads with different thread IDs.

How are these threads created without any system call? And if jvm created threads in user space, then they should not be listed ps -eLf.

The output of the strace command

 mprotect(0xf95000, 8876032, PROT_READ|PROT_EXEC) = 0 munmap(0xf7762000, 92395) = 0 mmap2(NULL, 331776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xfffffffff770f000 mprotect(0xf770f000, 4096, PROT_NONE) = 0 clone(child_stack=0xf775f494, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xf775fbd8, tls=0xf775fbd8, child_tidptr=0xffdb53d0) = 31692 futex(0xf775fbd8, FUTEX_WAIT, 31692, NULLthread #1 thread #5 thread #4 thread #3 ..... ) = 0 exit_group(0) = ? CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID, parent_tidptr = 0xf775fbd8, tls = 0xf775fbd8, child_tidptr = 0xffdb53d0) = mprotect(0xf95000, 8876032, PROT_READ|PROT_EXEC) = 0 munmap(0xf7762000, 92395) = 0 mmap2(NULL, 331776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xfffffffff770f000 mprotect(0xf770f000, 4096, PROT_NONE) = 0 clone(child_stack=0xf775f494, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xf775fbd8, tls=0xf775fbd8, child_tidptr=0xffdb53d0) = 31692 futex(0xf775fbd8, FUTEX_WAIT, 31692, NULLthread #1 thread #5 thread #4 thread #3 ..... ) = 0 exit_group(0) = ? 

I removed the initial system calls needed to start jvm. The only clone system call displayed is the one that creates the main thread.

+6
source share
2 answers

How are these threads created without a system call?

Of course, the clone system call is involved. Try strace with the -f option, ref: man strace

  -f Trace child processes as they are created by currently traced processes as a result of the fork(2) system call. On non-Linux platforms the new process is attached to as soon as its pid is known (through the return value of fork(2) in the parent process). This means that such children may run uncontrolled for a while (especially in the case of a vfork(2)), until the parent is scheduled again to complete its (v)fork(2) call. On Linux the child is traced from its first instruction with no delay. If the parent process decides to wait(2) for a child that is cur- rently being traced, it is suspended until an appropriate child process either terminates or incurs a signal that would cause it to terminate (as determined from the childรขs current signal disposition). 

And if jvm created threads in user space, then this should not be the listed ps -eLf.

The threads created by jvm are user level threads represented by LWP (kernel level abstraction) in linux.

see the LWP (native thread stream) and nlwp columns in ps -eLF result.

+2
source

On my machine running Oracle Java 8u5, I see very similar output from running only strace java ThreadTest . However, when I turn on the -f flag to execute child processes, I see dozens of clone() calls.

Your strace call tells it to just pay attention to the process running directly (the JVM bootstrap thread), and it spawns only the main thread. Then this thread is the one who calls clone() to create all of your workers.

+3
source

Source: https://habr.com/ru/post/971525/


All Articles