I read about threads in some operating system books , and i confuse about the following:
A. Some books when talk about:
many to one relation mean:many threads in user space map to one thread in kernel .
one to one relation mean:one thread in user space map to one thread in kernel
many to many relation mean: some threads in user space multiplex in lower or equal threads in kernel space .
B. On the other hand, some book talk about 4 relations between threads & processes
many to one ,mean:A process defines an address space and dynamic resource ownership. Multiple threads may be created and executed within that process.
one to one ,mean:Each thread of execution is a unique process with its
own address space and resources.
one to many ,mean: thread may migrate from one process environment
to another. This allows a thread to be easily moved among distinct systems.
many to many ,mean:Combines attributes of (many to one) and (one to many) cases.
The cases in A is clear but in B i didn't understand number 3 , would you please explain it ?
Thanks.
I am not sure which book you are reading, but it seems to be it was written long time ago and now doesn't have any practical usage. For instance, there is no system I know of which allows thread migration. I doubt there ever was one practically used.
As for user-spaced threads modern systems do not use them. All platforms I know of use threads which are managed by kernel (i.e. kernel threads). All threads within the same process have access to this process memory, but can't go outside of it.
A thread is piece of a process ;while a process is a program in execution mode which requires resources.
Related
In silberschatz "Operating System Concepts" book, section 4.3.2 says that
one-to-one model provides more concurrency than the many-to-one model
by allowing another thread to run when a thread makes a blocking
system call. It also allows multiple threads to run in parallel on
multiprocessors.
I have two questions here:
How can one thread be blocked and other mapped on kernel thread?
Dont we know that if one thread is blocked, entire process of that
user-level thread is blocked?
The OS considers user-level threads
as one thread only. It cant be assigned to multiple
processors/cores. Isn't the below given line contradicting that
idea?
It also allows multiple threads to run in parallel on
multiprocessors
Your understanding of user level threads and kernel level threads is not correct, in particular you need to understand how user level threads are mapped to kernel level threads. So first lets define some terms
Kernel thread
A thread (schedulable task) that is created and managed by the kernel. Every kernel level thread is represented by some data structure which contains information related to the thread. In the case of Linux it is task_struct. Kernel threads are the only threads that are considered by the CPU scheduler for scheduling.
Note : Kernel thread is a bit of misnomer as Linux kernel doesn't distinguish between a thread and a process, schedulable task would better describe this entity.
User thread
A thread that is created and managed by some library such as JVM above kernel level. The library that creates these threads is responsible for their management that is which thread runs and when.
User level to kernel level mapping
Now you can create as many user level threads as you want but to execute them you need to create some kernel level thread (task_struct). This creation of kernel level threads can be done in many ways
One to one model
In this case whenever you create a user level thread your library asks the kernel to create a new kernel level thread. In the case of Linux your library will use clone system call to create a kernel level thread.
Many to one model
In this case your library creates only one kernel level thread (task_struct). No matter how many user level threads you create they all share the same kernel level thread, much like the processes running on a single core CPU. The point to understand is that your library here acts much like the CPU scheduler, it schedules many user level threads on single kernel level thread.
Now to your question
The OS considers user-level threads as one thread only. It can’t be
assigned to multiple processors/cores. Isn't the below given line
contradicting that idea?
If you were using many to one model, in that case you will have only one kernel level thread for all of your user level threads and hence they cannot run on different CPU’s.
But if you are using a one to one model then each of your user level threads has a corresponding kernel level thread that can be scheduled individually and hence user level threads can run on different CPU’s given that you have more than one CPU.
You are suffering from a confusing book.
There are real threads (aka kernel threads, 1 to 1 model) and there are simulated threads (aka user threads, many to 1 model).
Some books make this more confusing by throwing a hypothetical many to many model.
User threads are obsolete. Any operating system book worth reading these days would treat them that way and describe them in historical terms.
How can one thread be blocked and other mapped on kernel thread? Dont we know that if one thread is blocked, entire process of that user-level thread is blocked?
You either have user threads or kernel thread. An application that did both would be royally screwed up.
The OS considers user-level threads as one thread only. It cant be assigned to multiple processors/cores. Isn't the below given line contradicting that idea?
In ye olde days a process was considered to be an execution stream and an address space. There were no threads. When threads became necessary (largely due to the need for Ada support), they were simulated using timers. The behavior of threads varied by operating system.
In Eunuchs variants, blocking calls block the process entirely. Thus in simulated (user) threads a blocking call in one thread would block all threads. This is not true on all operating systems.
Now, a process is one or more execution streams and an address space. That is what you ought be learning; not a bunch of technobabble.
A book that talks about threads in terms of 1-to-1 or many-to-1 models is only fit to line cat boxes.
While going through OPERATING SYSTEM PRINCIPLES, 7TH ED
(By Abraham Silberschatz, Peter Baer Galvin, Greg Gagne), i encountered a
statement in Thread Scheduling Section.It is given as -:
To run on a CPU, user-level threads must ultimately be mapped
to an associated kernel-level thread, although this mapping may
be indirect and may use a lightweight process (LWP).
The first half of the statement i.e
To run on a CPU, user-level threads must ultimately be mapped to an associated kernel-level
is trying to say that When a user level thread is executed ,it will need support from kernel thread like system calls.
But i am completely stuck in other half i.e
although this mapping may
be indirect and may use a lightweight process (LWP)
What does it really mean ???
Please help me out !
You're reading a book that is notoriously crapola. Threads are implemented in two ways.
In the olde days (and still persists on some operating systems) there were just processes. A process consisted of an execution stream and an address space.
When languages that needed thread support (e.g., Ada—"tasks") there was a need to create libraries to implement threads. The libraries used timers to switch among the various threads within the process. This is poor man's threading. The major drawback here is that, even when you have multiple processors, all the threads of a process run on the same processor. The threads are just interleaved execution within a single process that executes on one processors.
These are sometimes called "user level threads." Some books call this the "many-to-one model."
To say
To run on a CPU, user-level threads must ultimately be mapped to an associated kernel-level thread
is highly misleading. There [usually] ARE no kernel threads in this model; just processes. Multiple threads run interleaved in a process. To call this a mapping "to an associated kernel-level thread" is misleading and overly theoretical.
This is mumbo jumbo.
although this mapping may be indirect and may use a lightweight process (LWP)
The next stage in operating system evolution here was for the operating system to support threads directly. Instead of a process being an execution stream + address-space, a process became one-or-more-threads + address-space. Instead of scheduling processes for execution, the OS schedules threads for execution.
Those are kernel threads.
Your book is making the simple complex.
These days the term Light Weight Processes and threads are used interchangeably.
although this mapping may be indirect and may use a lightweight
process (LWP)
I know the above statement is confusing(Notice the 2 mays). I can think only 1 thing which the above statement signifies is that:
Earlier when linux supported only user-level threads, the kernel was unaware of the fact that there are multiple user-level threads, and the way it handled these multiple threads was by associating all of them to a light weight process(which kernel sees as a single scheduling and execution unit) at kernel level.
So associating a kernel-level thread with each user-level thread is kind of direct mapping and associating a single light weight process with each user-level thread is indirect mapping.
What is the difference between kernel threads and user threads? Is it that kernel thread are scheduled and executed in kernel mode? What are techniques used for creating kernel threads?
Is it that user thread is scheduled, executed in user mode? Is it that Kernel does not participate in executing/scheduling user threads? When interrupts occur in executing user thread then who handles it?
Whenever, thread is created a TCB is created for each. now in case of user level threads
Is it that this TCB is created in user's address space ?
In case of switching between two user level threads who handles the context switching ?
There is a concept of multithreading models :
Many to one
One to one
Many to Many.
What are these models? How are these models practically used?
Have read few articles on this topic but still confused
Wants to clear the concept ..
Thanks in advance,
Tazim
Wikipedia has answers to most if not all of these questions.
http://en.wikipedia.org/wiki/Thread_(computer_science)
http://en.wikipedia.org/wiki/Thread_(computer_science)#Processes.2C_kernel_threads.2C_user_threads.2C_and_fibers
What is the difference between kernel threads and user threads?
Kernel threads are privileged and can access things off-limits to user mode threads. Take a look at "Ring (Computer Security)" on Wikipedia. On Windows, user mode corresponds to Ring 3, while kernel mode corresponds to Ring 0.
What are techniques used for creating kernel threads?
This is extremely dependent upon the operating system.
now in case of user level threads Is it that this TCB is created in user's address space ?
The TCB records information about a thread that the kernel uses in running that thread, right? So if it were allocated in user space, the user mode thread could modify or corrupt it, which doesn't seem like a very good idea. So, don't you suppose it's created in kernel space?
What are these models? How are these models practically used?
Wikipedia seems really clear about that.
Kernel thread means a thread that the kernel is responsible for scheduling. This means, among other things, that the kernel is able to schedule each thread on different cpus/cores at the same time.
How to use them varies a lot with programming languages and threading APIs, but as a simple illustration,
void task_a();
void task_b();
int main() {
new_thread(task_a);
new_thread(task_b);
// possibly do something else in the main thread
// wait for the threads to complete their work
}
In every implementation I am familiar with, the kernel may pause them at any time. ("pre-emptive")
User threads, or "User scheduled threads", make the program itself responsible for switching between them. There are many ways of doing this and correspondingly there is a variety of names for them.
On one end you have "Green threads"; basically trying to do the same thing as kernel threads do. Thus you keep all the complications of programming with real threads.
On the opposite end, you have "Fibers", which are required to yield before any other fiber gets run. This means
The fibers are run sequentially. There is no parallell performance gains to be had.
The interactions between fibers is very well defined. Other code run only at the exact points you yield. Other code won't be changing variables while you're working on them.
Most of the low-level complexities programmers struggle with in multithreading, such as cache coherency (looking at MT questions on this site, most people don't get that), are not a factor.
As the simplest example of fibers I can think of:
while(tasks_not_done) {
do_part_of_a();
do_part_of_b();
}
where each does some work, then returns when that part is done. Note that these are done sequentially in the same "hardware thread" meaning you do not get a performance increase from parallellism. On the other hand, interactions between them are very well defined, so you don't have race conditions. The actual working of each function can vary. They could also be "user thread objects" from some vector/array.
Essentially user threads run in the context of a user with the appropriate privilege levels e.g. user threads most certainly won't have access to kernel-level memory/data structures/routines etc. Whereas Kernel threads run in the context of the OS kernel thus giving them privileges to execute code which has access to low level kernel routines/memory/data structures.
Is there any comprehensive overview somewhere that discusses all the different types of threads and what their relationship is with the OS and the scheduler? I've heard so much contradicting information about whether you want certain types of threads, or whether thread pooling is a performance gain or a performance hit, or that threads are heavy weight so you should use these other kind of threads that don't map directly to real threads but then how is that different from thread pooling .... I'm paralyzed. How does anyone make sense of it? Assuming the use of a language that actually directly interacts with threads (I'm aware of concurrent languages, implicit parallelism, etc. as an alternative to needing to know this stuff but I'm curious about this at the moment)
Here is my brief summary, please comment and edit at will:
There are no hyperthreads, unless you're talking about Intel's hyperthreading in which case it's just virtual cores.
"Green" usually means "not OS-level" (scheduled/handled by a VM, which may or may not map those unto multiple OS-level threads or processes)
pthreads are an API (Posix Threads)
Kernel threads vs user threads is an implementation level (user threads are implemented in userland, so the kernel is not aware of them and neither is its scheduler), "threads" alone is generally an alias for "kernel threads"
Fibers are system-level coroutines. They're threads, except cooperatively multitasked rather than preemptively.
Well, like with most things, it's common to not just care unless threading is identified as a bottleneck. That is, just use the threading functionality that your platform provides in the usual manner and don't worry about the details, at least in the beginning.
But since you evidently want to know more: Usually, the operating system has a concept of a thread as a unit of execution, which is what the OS scheduler handles. Now, switching between OS-level threads requires a context switch, which can be expensive and can become a performance bottleneck. So instead of mapping programming-language threads directly to OS threads, some threading implementations do everything in user space, so that there is only one OS-level thread that is responsible for all the user-level threads in the application. This is more efficient both performance- and resource-wise, but it has the problem that if you actually have several physical processors, you cannot use more than one of them with user-level threads. So there's one more strategy of allocating threads: have multiple OS-level threads, the number of which relates to the number of physical processors you have, and have each of these be responsible for several user-level threads. These three strategies are often called 1:1 (user threads map 1-to-1 to OS threads), N:1 (all user threads map to 1 OS thread), and M:N (M user threads map to N OS threads).
Thread pooling is a slightly different thing. The idea behind thread pooling is to separate the execution resources from the actual execution, so that you have a number of threads (your resources) available in the thread pool, and when you need some task to be executed, you just pick one thread from the pool and hand the task over to it. So thread pooling is a way to design a multi-threaded application. Another way to design would be to identify the different tasks that will need to be performed (e.g., reading from a network, drawing the UI to the screen), and create a dedicated thread for these tasks. This is mostly orthogonal to whether the threads are user- or OS-level concepts.
Threads are the main building block of a Process in the Windows win32 architecture. You can ignore green threads, fibers, green fibers, pthreads (POSIX). Hyper threads don't exist. It is "hyper threading" which is a CPU architecture thing. You cannot code it. You can ignore it.
This leaves use with threads. Indeed. Only threads. A kernel thread is a thread of the kernel, which lives in the upper 2GB (sometimes upper 1GB) of the virtual memory addess space of a machine. You cannot touch it. So you can ignore it most of the time (unless you are writing kernel mode ring-0 code).
Only user threads are the ones you should be concerned about. They come in two flavors: main thread and auxiliary threads. Each process has at least one main thread, it is created for you when you create a process (CreateProcess API call). Auxiliary threads can do tasks that take long and otherwise interrupt the user experience. In C#/,NET you can use the BackgroundWorker class to easily create and manage threads.
Threads have several properties. This may have lead to all "kinds" of threads. But worker threads are probably the only ones you should be worried about when you start dealing with threads.
I learned a lot reading these slides.
I came across this after looking at Unicorn.
What is the best definition of a thread and what is a process?
If I call a function, how do I know that a thread is calling it or a process (or am I not understanding it??!). This is in a multi-core system (quadcore).
From http://wiki.answers.com/Q/What_is_the_difference_between_a_computer_process_and_thread:
A single process can have multiple threads that share global data and address space with other threads running in the same process, and therefore can operate on the same data set easily. Processes do not share address space and a different mechanism must be used if they are to share data.
If we consider running a word processing program to be a process, then the auto-save and spell check features that occur in the background are different threads of that process which are all operating on the same data set (your document).
One thing to add is how does a multi-core processor handle this. Think of a thread as the sequential execution of your code.
A core in a CPU can only execute one thread at a time. So if this thread is blocked because the program is waiting for an I/O operation to finish, the process is blocked (very simplified example: Word not responding). Multi-threading allows us to execute multiple code paths at the same time. "Same time" is a bit of a lie, since only one thread can actually execute at a time in a core, but the CPU gives some small chunk of time to each thread, so it appears as if all these threads are executing at the same time. A good example here is the spell checker in Word.
If you have multiple cores, the only difference is that in an N-Core CPU you can have N threads executing at the same time. To simplify a lot, it doesn't matter what process the threads belong to. To simply even further, you'd expect a N times performance increase. :-D
In every modern OS I know of, everything runs in a thread, which runs in a process.
The OS can keep track of multiple processes, and each process can host an arbitrary number of threads. So all code is executed within a thread and within a process (since the thread runs in a process).
The main distinction between the two is that each process has its own virtual address space. Separate processes do not have access to each others' data, file handles or anything else, and are essentially not aware that other processes exist.
On the other hand, every thread in a process share the same address space, and all threads can therefore inspect or modify each others' data, call the same functions and everything else.
It is often (but not always) the cases that one program consists of one process and a number of threads.
A process is composed of one or more threads (one by default for most environments). A process can create additional threads though.
Like the previous answer says, each Process has its own memory space (each can have a pointer to 0x12345, with that memory location having different values for each process), while all the Threads of a process would actually point to the exact same memory location, since they're all in the same memory space.
When calling a function, it's almost always called on the same thread that the caller is running on. In Objective-C, there are exceptions (performSelectorOnMainThread), and there might be for other languages as well, but that sort of functionality is necessary only in special cases.
From a user's point of view, the main distinction is that threads share memory with each other, while processes do not. That means you can easily share data between threads, while processes require some kind of OS call to do so.
Some call this a benifit of threads, but sharing data between multiple threads of control is fraught with danger, so it can be argued that processes lead to more reliable code.
There's a lot more to it, particularly if you are an OS person.