When a thread is yielded from CPU windows stores the CONTEXT (current state such as CPU registers, program counters Etc) information of the current thread and loads the CONTEXT of the new thread which will run in the CPU.
Why? A thread is yielded when executing an instruction, How the thread will resume from same point when it is rescheduled in CPU. Context information is stored while yielding and loaded when thread in rerun.
Note: yielding from CPU=Coming out of CPU
If there is high Context switching then system would spend more time on doing context switching than doing meaningful work.
When a thread moves out of CPU it is called as yielding.
When a thread can yield?
Thread which is running on CPU can yield out of the CPU under following key condition
Thread decides to yield by itself because of the logic in code executed by the thread. Generally a thread will voluntarily yield by calling Sleep(0) or SwitchToThread. When a thread voluntarily yields it is placed at the end of runnable list.
Ex: SQL Server thread will yield after sorting 64K of sort records.
Thread which is running on the CPU will be forced to yield from CPU when a thread with higher priority is ready to run. When a thread is preempted it is placed in the beginning of the runnable list.
All the threads which is executed in operating system will get a time slice called as quantum. When a thread completes its quantum it is yielded and next thread is run. If there is no other thread is ready to run than thread run for another quantum.
Thread is terminated when it finishes execution and destroyed by calling TerminateThread
Thread and process priorities
windows supports thread priority level ranging from 0 (Lowest) to 31 (Highest). If all the threads have same priority they are scheduled in round robin basis, but in reality threads running on OS will have different priorities. Among all the threads which can be run windows scheduler picks thread with highest priority to run first. Priority of a thread can be changed using WINAPI SetThreadPriority, Similarly priority of a process can be set while creating the process (WINAPI CreateProcess dwCreationFlags ) ,using WINAPI SetPriorityClass after the process is created and by using tools like task manager.
Let us attach the debugger to SQL Server process and see how to view the threads, thread stack and how SQL Server threads wait with out being scheduled.
Download the windows debugger from below link
Windbg 32-bit package:
Windbg X64 package:
1. Start SQL Server in your test system.
2. Attach the debugger to SQL Server process. Refer below image. If you have more than one instance use the process id to attach with correct SQL Server process.
3. On command window type
4. Type .reload /f and hit enter. This will force debugger to immediately load all the symbols.
5. Verify if symbols are loaded for SQL Server by using the debugger command lmvm
!peb to display the information about process from process environment block.
7. Type ~ to display all the threads in the process. First column in the output represents thread ID.
8. To look at the stack of a specific thread,switch to the thread using thread ordinal (or) thread ID.
Debugger command ~ displays all the thread’s of the process.
Thread ordinal: is decimal value used by debugger to identify the thread starts from 0 (First columns in below output).
Thread ID : Is the ID assigned to each thread by operating to system. You can switch to a thread using thread ID by debugger command ~~[ThreadID]s (4th column in ~ output )
In the below image I have printed all the thread’s and stack of thread ordinal 8 which is scheduler monitor thread.
9. Type g in command prompt to resume the process.
10. Connect to SQL Server from management studio. Run select * from sysprocesses. All the sessions which has a non zero value for KPID has a valid windows thread associated with the session. When executing queries which choose parallel plan there will be more than one row for same session and each rows will have different KPID.
11. To look at the thread stack of a session which is currently executing a task or background process . Convert KPID value associated with session in sysprocess in Hexadecimal value and type below command window of debugger.
~~[Hex value of a thread]s
12. Let us create a small blocking scenario to understand how threads wait in SQL Server.
create table a (A int)
insert into a values (1);
update a set A =1+1
select * from a
— Session-2 will be blocked. Look at the stack of blocked thread
13. Run select * from sysprocesses where blocked<>0
Identify the KPID of the session which is blocked.
14. Convert KPID in to hexadecimal value
15. Break the debugger to execute the debugger commands (CTRL+B) or 7th Icon in menu bar.
16. Look at the stack of the thread which is waiting for lock (Blocked) by using the Hex value of KPID
~~[Hex value of KPID]s
17. Above thread from second session which we created is waiting for an event using WaitForsingleObject. When the first session releases the lock this thread will be signaled and resumes execution.
We will see the details about WaitForsingleObject ,Waitformultipleobjects, Event (Manual auto reset) etc. in more details in forthcoming blogs
The views expressed on this website/blog are mine alone and do not reflect the views of my company. All postings on this blog are provided “AS IS” with no warranties, and confers no rights.