kernel Thread VS user-level thread

kernel Thread VS user-level thread

Post by Jimmy Zhan » Sat, 23 Mar 2002 18:13:47



I got a question concerning the pthread implementation in Linux.
Well, I have all the world telling me pthread for linux is a user-space
thread model, but when I ran a multi-threaded app on linux and turn
on top, I remember seeing multiple copies of the same process on the
process list so a scheduler sees each thread as a process and schedule
it accordingly. But is this what I am supposed to expect from a kernel
thread implementation?

Jimmy Zhang

 
 
 

kernel Thread VS user-level thread

Post by mlw » Sun, 24 Mar 2002 09:04:31



> I got a question concerning the pthread implementation in Linux.
> Well, I have all the world telling me pthread for linux is a user-space
> thread model, but when I ran a multi-threaded app on linux and turn
> on top, I remember seeing multiple copies of the same process on the
> process list so a scheduler sees each thread as a process and schedule
> it accordingly. But is this what I am supposed to expect from a kernel
> thread implementation?

pthreads are implemented as kernel threads. They use the "clone()" call.

 
 
 

kernel Thread VS user-level thread

Post by Ed Skinne » Tue, 02 Apr 2002 22:56:58


     The Linux scheduler (in 2.4, at least) deals with something called a
task_struct which is,
at its most fundamental level, a thread. User-level threads and
kernel-level threads are, at
least to the scheduler, the same thing: they both have task_struct's and
the values present
therein will determine when they get to run.
     A process, on the other hand, *MAY* contain more than a thread or, to
say it differently,
several threads may share the same space in memory. When that happens, we
could say
there is a process with several threads, all sharing the process's memory
space. Technically
speaking, however, in Linux the "memory space" is defined by a separate
structure and each
thread (task_struct) contains a pointer to its memory space descriptor.
When several threads
all point to the same memory space descriptor, they have the same memory
space. (Multiple
threads within a process have more in common than just their memory space,
but you get the
idea, I hope.)
     Some programs such as "ps" and "top" are process-centric. That is,
they are not aware of
threads. They were written before threads were implemented in Unix and,
for various reasons,
they have not been changed: lots of tools build on other tools and when a
fundamental change
occurs (such as the addition of threads to an architecture that used to be
based on processes),
someone has to decide which tools to update (and deal with the programs
built upon them which
may then become "broken") and which tools to leave ignorant. "ps" and
"top" (and many others)
are unaware of the fact that Linux is basically a thread-executing system.
(There is no single
entity known as a "process" in Linux: it is a collection of related
items.)
     Finally, there are user-level threads and kernel-level threads. The
only real difference is
whether or not the thread runs in user-mode or kernel-mode, and that makes
all the difference
in the world.
     First, a user-level thread begins when either a fork() or a
pthread_create() occurs. As you
may know, fork() creates a new process --- uhm, I like to think of a
process as "a thread with
a unique memory space". If you type a command such as "ls -l" into a
shell, the shell does a
fork() and the new process looks for the "ls" program and executes it via
the execve() call. The
new "thread with a unique memory space" (the process) executes the code
named "ls" and
essentially begins that execution at the function named "main". Similarly,
if you write a program
in C, compile and tell the shell to execute it, the shell will create a
new process ("thread with
a unique memory space") and execute your code starting at the function
named "main." [I'm
simplifying here a little bit. There is some code executed before reaching
"main" but, for the
purpose of this discussion, it isn't very interesting.]
     During the life-time of this new program (or we could call it a
process, or be even more
accurate and call it a thread), it will execute the code we've indicated,
call subroutines,
add numbers, and so forth. And we probably expect it will generate some
output, maybe after
reading some input. These are accomplished via system calls, and here is
where the kernel-
thread comes into play. When a user-mode thread issues a system call, the
processor changes
mode into the supervisor (or kernel) mode (or state). What is executing is
now a kernel-mode
thread. A kernel-mode thread is the same as a user-mode thread except that
one is executing
in supervisor mode (and "sees" memory the same as the kernel) whereas the
other executes
in user mode and, therefore, "sees" only the memory we call user-memory
(or user-space).
     So, here is the final answer: a kernel-thread is essentially the same
as a user-thread except
that the kernel-thread executes 100% of its lifetime in supervisor mode.
     [PAUSE FOR FEELING OF DEEP UNDERSTANDING HERE. REREAD ABOVE UNTIL
THAT HAPPENS.]
     One more concept to help get everything in place: kernel
preemptability.
     Linux (prior to 2.5.something -- as announced about one month ago) is
a non-preemptible
kernel. That means that when a thread is running in user-mode, Linux may
decide to go and
run some other user-mode thread at just about any moment. On the other
hand, when a user-
mode thread issues a system call, as described above it now starts
executing in supervisor
mode and, hence we call it a kernel thread. When a thread is running in
kernel-, or if you
prefer, supervisor-mode, Linux will *not* run any other thread until the
thread in kernel-mode
finishes running in kernel-mode.
     So, when does a kernel-mode thread finish running in kernel-mode? In
the case of the user
program that issues a system call to do a read or a write, the kernel-mode
(thread) operation
continues until the read or write operation is finished, or until the
device driver indicates that
there will be a delay and someone else should be allowed to run. In cases
where the program
is simply reading the next byte from a buffer a new data and the driver
can make the desired
byte available immediately, the kernel-mode execution will end when the
driver indicates it
has completed the user's request (to read a byte). The kernel-mode thread
will make its way
through to the end of the device driver, go back to the part of Linux that
called the device
driver (because the user-mode thread issued a system call), and, thence,
back into the user-
mode and to the next line of code in user-space after the read operation.
     In the past, people used kernel-threads because 1) they executed in
the priviledged kernel-
mode of the processor and because 2) once started, they were not
preemptible. In practice,
kernel-threads typically had some sort of input queue of things to be
done. This queue was
often built by an interrupt service routine and, if several interrupts
happened in quick succession,
there might be several things to do in the queue. When the kernel-thread
begins processing
that work, it would "run to completion" and process all of the queued
work. No other process
(thread) would be executed because Linux used to say, "if you're running
in the kernel-mode,
I won't go and run someone else until you tell me you are finished." That
was the primary
virtue of a kernel thread. It "ran to completion."
     About a month ago, however, Linus decided to make the kernel
preemptible. The change
was incorporated in one of the experimental 2.5 kernels that are presently
under development.
Presumably it will arrive in the 2.6 series of stable kernels that most of
us will start seeing
in a few months or so. Once that happens, one of the "virtues" of
kernel-threads, the fact
that they are not preemptible, will disappear. At that point,
kernel-threads will be just like
user-threads and preemption could occur at any time.
     There will still be a good reason to have kernel-threads: the fact
that they execute in
kernel-mode allows them to do "interesting" (dangerous) things that can be
very useful.


> I got a question concerning the pthread implementation in Linux.
> Well, I have all the world telling me pthread for linux is a user-space
> thread model, but when I ran a multi-threaded app on linux and turn
> on top, I remember seeing multiple copies of the same process on the
> process list so a scheduler sees each thread as a process and schedule
> it accordingly. But is this what I am supposed to expect from a kernel
> thread implementation?

> Jimmy Zhang

--

 
 
 

1. threads packages: kernel threads vs. user threads

Hello,

There seem to be other C or C++ language compatible thread packages
besides the standard POSIX 1003.1-2001 thread-related system calls.
For instance Qt implements some thread class code. I would imagine
that implementations which use kernel threads as opposed to user
threads would be based on the POSIX calls. Is this correct? What
other thread packages are available besides the POSIX ones? Just
speculating. Which packages are kernel thread based and which
ones are user thread based?

Thank you for your feedback,

Neil

2. plip

3. kernel thread VS user space thread in linux

4. Mouse with svgalib?

5. HELP: communication interface between kernel thread and user thread.

6. Auth by IP

7. PTHREADS kernel/user level threading?

8. df -k info doesn't add up!

9. Any user-level thread package experiences ?

10. A newbie question about user-level thread

11. Scheduling for user-level threads

12. User-level threads implementation problem

13. one-to-one mapping between user-level threads and LWPs