win32 programming lesson 10: thread scheduling and priorities

21
Win32 Programming Lesson 10: Thread Scheduling and Priorities

Upload: helena-oliver

Post on 31-Dec-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

Win32 ProgrammingLesson 10: Thread Scheduling and Priorities

Where are we? We’ve got thread basics worked out… But it’s very helpful to understand how the

OS deals with thread scheduling This lesson, we’ll work on scheduling threads

– understanding how each one gets executed on the machine

Thread Context Remember the kernel keeps a copy of the

thread context which contains important runtime information Such as?

Every 20ms or so, Windows looks at the thread contexts on the machine and decided which to allow to run This is known as a context switch – see a tool like

Spy++

Context Switch (cntd) After about 20ms, the Operating System

saves the processor’s internal state to thread’s context and looks for the next thread to execute

This cycle continues until the system shuts down

Only “schedulable” threads can be run

Example: Notepad When Notepad is just sitting about as a

Window with nothing to do, it is not marked schedulable

When the OS sees that the Windows has been moved or typed in, the thread is marked as schedulable NB: This is not the same as actually running the

thread – that still depends on the OS scheduler

Ensuring you get run Often, want to make sure that there is no

latency between a particular action (maybe data arriving on a port) and response

How? Sorry, can’t be done easily. Windows is not a

Real-time operating system

Suspending and Resuming Threads DWORD ResumeThread(HANDLE hThread) DWORD SuspendThread(HANDLE hThread) NB: A thread can be suspended multiple

times. If a thread is suspended more than once, it must be resumed more than once before it becomes schedulable

Danger, Will Robinson! Randomly suspending a thread can cause

deadlocks. Don’t do this unless you know exactly what the thread is doing!

Example: Suspending a Process Why is the idea of suspending a process

meaningless? What do we mean when we do this? Let’s look at an example from VS2013

Sleeping A thread can tell the OS that it wants to go to sleep

(that is, be unscheduled for a certain amount of time) VOID Sleep(DWORD dwMilliseconds)

Calling Sleep automatically gives up the rest of this time slice

The time to sleep is approximate – remember, Windows is not a real-time OS

You can call Sleep with the parameter INFINITE. This is not useful.

You can call Sleep with the parameter 0 to give up the remainder of this timeslice

Switching to another Thread Imagine you have a low-priority thread

locking a resource… Can use BOOL SwitchToThread()

See if another thread is CPU starved and waiting Returns FALSE if no other thread can run Similar to Sleep except lower-priority threads

also execute

Aside: ThreadExecution Times Naively, most simply take the time at the start of a

code block and the end, and subtract No guarantee there weren’t thread switches in there!

Instead, can use BOOL GetThreadTimes(    

HANDLE hThread,     PFILETIME pftCreationTime,      PFILETIME pftExitTime,     PFILETIME pftKernelTime,        PFILETIME pftUserTime);

Thread Context Revisited There is actually a structure for the thread context

documented by Microsoft… ooh! Declared in winnt.h (see here for details) So, if we wanted to we could stop a running thread

and modify its context… well, let’s look at the example in the book…

Thread Priorities Each thread can execute at a different priority Priorities are assigned from 0 (lowest) to 31

(highest) When the scheduler assigns a thread it always

passes control to a priority 31 thread if there are any available to run

And so on, down the priorities…

Caveat Emptor Microsoft does not fully document the

behavior of the scheduler Microsoft tells you the scheduler is subject to

change Microsoft provides an abstraction layer – you

can’t talk to the scheduler directly

Windows Priorities Six process levels

Real-time: respond immediately to time-critical messages. This priority is higher than task manager – it you use it, you can hang the machine! BE CAREFUL!

High: threads which must respond. This is how task manager runs

Above normal: between high and normal Normal: No special scheduling needs Below normal: between normal and idle Idle: Only run when the system is basically idle

And then threads You can set the relative thread priorities too… This sets the overall priority So, this all sounds good, but how do you do

it?

Programming Priorities Parameter to CreateProcess REALTIME_PRIORITY_CLASS,

HIGH_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, IDLE_PRIORITY_CLASS

DIY A process can also call BOOL

SetPriorityClass(HANDLE hProcess, DWORD fwdPriority)

Example: SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS)

Also DWORD GetPriorityClass(HANDLE hProcess)

Similarly SetThreadPriority(HANDLE hThread, int nPriority)

Tweaking the Scheduler Can optimize the foreground or background

processes

Affinities Can control which processor a thread

executes on, on a multi-processor machine Why does this matter?

Assignment Threading is a very useful technique Write a network server which listens on Port 31337 The server should handle multiple clients, creating a new

thread for each client The server simply echoes back what you type (but waits for a

newline) A session is closed when the string “close” is typed to the

server The console should provide a simple output which details the

number of threads in use when asked Also, the console should remain responsive to a “shutdown”

request