Linux applications generally fork then exec (with execve() ), but Java applications, and certain Apache MPMs use threading. If forking, uses the fork + exec to spawn a process, what is the high level version for threading? How does JVM or Worker MPM spawn threads?
The idea behind threads and processes is about the same: You fork the execution path. Otherwise threads and processes differ in things like memory. I.e. processes have different VM space while threads share whatever existed before the split.
Underlying both threading and forking work by using the clone() call (man 2 clone):
Unlike fork(2), clone() allows the child process to share parts of its execution context with the calling process, such as the memory space, the table of file descriptors, and the table of signal handlers. (Note that on this manual page, "calling process" normally corresponds to "parent process". But see the description of CLONE_PARENT below.)
The main use of clone() is to implement threads: multiple threads of control in a program that run concurrently in a shared memory space.
The differences come from the flags that are passed to clone(). As you can see from the man page, fork and threading are just a set of predefined parameters to clone(). However one can also do custom stuff with it.
Most non-Unix multiprocessing operating systems (OSes) use a "spawn()" call or something similar to generate a new OS process or control flow. Spawn() tends to be a very complex call, with lots of options and lots of overhead. One of Unix's innovations was to provide a much lower overhead way of creating processes - fork(). Unix took care of the many necessary options to spawn() by allowing arbitrary amounts of processing before the other half of spawn(), with exec().
As Unix and variants thereof were used more and more, low overhead process creation was found to be useful, and was used. In fact, it was used so much, that people wanted even lower overhead ways to create processes, and so the idea of "threads" was born. Originally, threads were handled completely by the originating process (and programs like the JVM may do this with "green threads"); but handling multi-thread scheduling is tricky and was frequently done incorrectly. So there's an easier, intermediate way of doing threads, where the OS handles the scheduling but some overhead is saved by (typically) sharing address space between threads.
Your question is difficult to answer because there are several different but related concepts that are all "threads," and for detail you need an adjective to describe which one you're referencing. On the other hand, understanding the differences will probably lead you to the specific answer you want. Look up things like "lightweight processes," "user threads," and "rfork()" for more info.
Threads and forking are actually two different concepts, both of which exist in Unix/Linux systems (and both of which can be used in C/C++).
The idea of a fork() is (very basically) a creation of a separate process which has the same execution code as the parent process, and which begins execution at the fork line. The purpose of using forks with exec functions is that exec functions close the process that called them when they end. So, you usually fork, getting the PID of each process (the child's is always 0), and make the parent wait until the child is finished executing the exec function.
Threads are used for parallelism (recall that the parent waits on the child, usually, in a forked program). A thread, such as pthread in C/C++(do a Google search), will run in parallel to the main process, and can share global variables and global functions with the original program. Since Java threads behave similarly, I would imagine that they act more like these threads than like a forking process.
Basically, there is a difference between forking and threading. They do distinctly different things (although seeming similar). These concepts can be difficult to understand, but you can learn them through (extensive) research if you have an honest desire to understand them.
Please see these examples of how forks and threads can be called and used. Please note the behavior of the exec functions and their effects on the main program.
Both the JVM and Apache MPM rely on the kernel for native threads. That is, they use the OS for scheduling them. Of course both need their own API for keeping track of stuff.
Stackoverflow already has several questions dealing with this:
If forking, uses the fork + exec to spawn a process, what is the high level version for threading? How does JVM or Worker MPM spawn threads?
That is platform specific, but on linux and I would presume many other POSIX compliant systems they use the local implementation of pthreads, a userland threading API. E.g.:
#include <pthread.h> pthread_t tid; pthread_create(&tid, NULL, somefunc, NULL);
Starts a new thread calling
somefunc as its first point of execution.
You can also create threads -- distinct from forks in that they share the same global heap memory space of the parent process, instead of getting a duplicate copy of it (but note threads each execute with an independent stack memory of their own) -- with the
clone() system call, which is what pthreads is built on top of.