what is kernel thread dispatching? - multithreading

Can someone give me an easy to understand definition of kernel thread dispatching or just thread dispatching if there's no difference between the two?
From what I understand it's just doing a context switch while the currently active thread waits on a lock from another thread, so the CPU goes and does something else while this thread is in blocking mode.
I might however have misunderstood.

It's basically the process by which the operating system determines which of the many active threads is sent (dispatched) to the CPU for processing at any given point.
Each operating system has its own implementation, but the basic concept is to keep a sorted list of threads by priority, and dispatch them as needed to the CPU. Time slicing is added to allow multiple programs to run concurrently, etc.

Related

Why does a process get blocked if a thread waits for I/O in many to one mapping

Why does a multi-threaded process using a user level thread library get blocked when one of its threads waits for an I/O? This makes sense, but when I think more, a question pops up. Can the user level thread library not schedule another thread?
OS can schedule only the processes(or jobs) , it in no way knows about the threads within a program and cannot schedule them as it wants.
when a part of the process ( here the thread which got blocked due to i/o) gets blocked for i/o operation, the os suspends the entire process , since the os deals only with the processes (not threads within the process).
As in the many to one model , there is only a single kernel , the process whose thread was blocked cant be executed until the blocked thread resumes.
whereas in a many to many or one to one model, each kernel runs its piece of code and is unaware of the threads blocked in the other kernels.
There's two types of thread. OS threads, and green threads (which is what I think you're talking about).
OS threads are scheduled by the operating system, and one will not block another (at least not on any OS you're likely to come across these days) unless you deliberately introduce something to synchronise them (e.g. Semaphores).
Green threads, where a process schedules different paths of execution for itself, will block unless the scheduler is clever enough provide (and therefore catch) all potentially blocking function calls and use them as a scheduling opportunity. This is also closely related to cooperative multitasking.
So the answer is yes, but only if written that way. Threads in Python famously were not written this way, read up on the GIL, and so would cause no end of problems. Python may have fixed this now.

Threads giving up CPU control - Seeming contradiction in textbook

I'm learning about threads and processes in an Operating Systems course, and I've come across an apparent contradiction in my textbook (Modern Operating Systems, 4th Ed. by Tanenbaum and Bos). I'm sure there's a something I'm misinterpreting here, it'd be great if someone could clear things up.
On page 106:
Another common thread call is thread_yield, which allows a thread to voluntarily give up the CPU to let another thread run. Such a call is important because there is no clock interrupt to actually enforce multiprogramming as there is with processes
Ok fine - so how I interpret that is that threads will never give up control unless they willingly cede it. Makes sense.
Then on page 116, in an example of threads mishandling shared information:
As an example, consider the errno variable maintained by UNIX. When a process (or a thread) makes a system call that fails, the error code is put into errno. In Fig. 2-19, thread 1 executes the system call access to find out if it has permission to access a certain file. The operating system returns the answer in the global variable errno. After control has returned to thread 1, but before it has a chance to read errno, the scheduler decides that thread 1 has had enough CPU time for the moment and decides to switch to thread 2.
But didn't thread 1 just get pulled from the CPU involuntarily? I thought there was no way to enforce thread switching as there is with process switching?
This makes sense if we're going about process-level threads instead of OS-level threads. The CPU can interrupt a process (regardless of what thread is running), but because the OS is not aware of process-level threads, it cannot interrupt them. If one thread inside the process wants to allow another thread to run, it has to specifically yield to the other thread.
However, most languages these days use OS-level threads, which the OS does know about and can pre-empt.
The confusion is that there are two different ways threads are implemented. In ye olde days there was no thread support at all. The DoD's mandate of the Ada programming language (in which tasks—aka threads—were is an integral part) forced the adoption of threads.
Run time libraries were created (largely to support Ada). That worked within a process. The process maintained a timer that would interrupt a threads and the library would switch among threads much like the operating system switches processes.
Note that this system only allows one thread of a process at a time to execute, even on a multiprocessor system.
Your first example is describing such a library but it is describing a very primitive thread library where thread scheduling is based upon cooperation among the various threads of the process.
Later, operating system started to develop support for threads. Rather than scheduling a process, the operating system schedules threads for execution. A process is then an address space with a collection of threads. Your second example is talking about this kind of thread.

Multithreading Models - One to Many model

I've been reading the dinosaur book and have been confused by this particular model.
The books says that for the one to many model "Thread management is done by the thread library in user space, so it is efficient; but the entire process will block if a thread makes a blocking system call. Also, because only one thread can access the kernel at a time, multiple threads are unable to run in parallel on multiprocessors"
What I'm confused about is what is meant by an entire process will block if a blocking system call is made? Does this mean if I have a multi-threaded program and one of it's threads blocks then all of its threads will have to wait, effectively stalling the program?
If a program undergoing execution causes a block with this model does it mean that another separate program can't be swapped in to be executed because the kernel thread is blocking? If that answer is YES another program(process) could be swapped in than why couldn't a multi-threaded program simply execute another one of its threads while the blocking thread is forced to wait?
If you manage your threads in user level, it means that the swapping is done by your application, not by OS scheduler. Each thread must reach some point where he surrenders (or loses) the control to the management mechanism, but that mechanism is also user-level, so if one of the threads is in the middle of doing a system call - your thread management system (and through that all the other threads) must wait until the kernel code is done.
The OS is still active all the time, and may still preempt the entire program, so other processes will not starve, only the internal "threads" you manage yourself. These threads can't get started during that block because the mechanism responsible of starting them is also blocked by the kernel.

Do threads get its own timeslice in user processes?

I can explain the question better with an example so I am using it?
Suppose our system is Round-Robin scheduled system with each time interval for execution 10ms. If we create two threads in our program , will each thread be executing 10ms or both in combine will execute 10ms?
If they take combine 10ms then who manages context switching between threads?
Note: I am not talking about kernel threads here.
In Linux, the threads contend for CPU with every other thread in the system. In POSIX terms, the threads have system contention scope.
Thus, for your example, each thread will get 10ms.
You can check this by:
Trying to set (via pthread_attr_setscope) the contention scope attribute to PTHREAD_SCOPE_PROCESS - should result in an error.
Get a thread attrbutes via pthread_getattr_np and check via pthread_attr_getscope that
the contention scope is PTHREAD_SCOPE_SYSTEM
Yes they too do have a time-slice.
In linux, threads vye for the resources such as memory,CPU or are waiting for some I/O event to occur. These threads under go through various states like idle,active,ready depending on the avalaibity of the resources. This all working is taken care by "Process Management Subsystem" which consists of Process Schedulars and manages the processes execution and their states.
One can also manipulate the time-period that a process can hold a resource like CPU.
Or the priority of a process can be changed( For e.g "nice").
-Sumeet

Pthread Concepts

I'm studying threads and I am not sure if I understand some concepts. What is the difference between preemption and yield? So far I know that preemption is a forced yield but I am not sure what it actually means.
Thanks for your help.
Preemption is when one thread stops another thread from running so that it may run.
To yield is when a thread voluntarily gives up processor time.
Have a gander at these...
http://en.wikipedia.org/wiki/Preemption_(computing)
http://en.wikipedia.org/wiki/Thread_(computing)
The difference is how the OS is entered.
'yield' is a software interrupt AKA system call, one of the many that may result in a change in the set of running threads, (there are lots of other system calls that can do this - blocking reads, synchronization calls). yield() is called from a running thread and may result in another ready, (but not running), thread of the same priority being run instead of the calling thread - if there is one.
The exact behaviour of yield() is somewhat hardware/OS/language-dependent. Unless you are developing low-level lock-free thread comms mechanisms, and you are very good at it, it's best to just forget about yield().
Preemption is the act of interrupting one thread and dispatching another in its place. It can only occur after a hardware interrupt. When hardware interrupts, its driver is entered. The driver may decide that it can usefully make a thread ready, (eg. a thread is blocked on a read() call to the driver and the driver has accumulated a nice, big buffer of data). The driver can do this by signaling a semaphore and exiting via. the OS, (which provides an entry point for just such a purpose). This driver exit path causes a reschedule and, probably, makes the read thread running instead of some other thread that was running before the interrupt - the other thread has been preempted. Essentially and simply, preemption occurs when the OS decides to interrupt-return to a different set of threads than the one that was interrupted.
Yield: The thread calls a function in the scheduler, which potentially "parks" that thread, and starts another one. The other thread is one which called yield earlier, and now appears to return from it. Many functions can have yielding semantics, such as reading from a device.
Preempt: an external event comes into the system: some kind of interrupt (clock, network data arriving, disk I/O completing ...). Whichever thread is running at that time is suspended, and the machine is running operating system code the interrupt context. When the interrupt is serviced, and it's time to return from the interrupt, a scheduling decision can be made to keep the interrupted thread parked, and instead resume another one. That is a preemption. If/when that original thread gets to run again, the context which was saved by the interrupt will be activated and it will pick up exactly where it left off.
Scheduling systems which rely on yield exclusively are called "cooperative" or "cooperative multitasking" as opposed to "preemptive".
Traditional (read: old, 1970's and 80's) Unix is cooperatively multitasked in the kernel, with a preemptive user space. The kernel routines are trusted to yield in a reasonable time, and so preemption is disabled when running kernel code. This greatly simplifies kernel coding and improves reliability, at the expense of performance, especially when multiple processors are introduced. Linux was like this for many years.

Resources