Download Thread Basics

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

C syntax wikipedia , lookup

Join-pattern wikipedia , lookup

C Sharp syntax wikipedia , lookup

Subroutine wikipedia , lookup

Parallel computing wikipedia , lookup

Process management (computing) wikipedia , lookup

C++ wikipedia , lookup

Scheduling (computing) wikipedia , lookup

Monitor (synchronization) wikipedia , lookup

Thread (computing) wikipedia , lookup

Transcript
Win32 Programming
Lesson 9: Jobs & Thread Basics
Where are we?




We’ve got processes sort of worked out…
But every process must have a thread
associated with it
This lesson, we’ll work on threads –
understanding threads is critical to
understanding Windows programming
Also, a little bit on jobs…
What is a Job



A collection of processes
For example, imagine interrupting the build in
Visual Studio
Windows 2000 offered a new kernel object to
allow this
Basic Idea

Create a Job Kernel Object


Place restrictions on the job object


CreateJobObject
SetInformationJobObject
Start up some processes…




CreateProcess
But, set CREATE_SUSPENDED flag
Assign processes to job
Start the primary thread of each process
Termination

You can stop all processes in a job simply by
terminating the Job Object

TerminateJobObject(HANDLE hJob, UInt
uExitCode)
Threads

Each thread is made up of two objects


A kernel object used by the Operating System to
manage the thread
A thread stack that maintains local variables and
function parameters as the thread executes
Threads v. Processes



Processes take up a lot more system resources
than threads
Processes are inert – they are simply a
container for one or more threads
Always solve a problem by adding threads not
processes if you possibly can!
When to Create Threads



Many applications only have one thread
The process terminates when the primary
thread finishes
However, processes can have as many threads
are you like… and there’s no reason for the
CPU to be idle (unless you’re on a laptop!)

Example: Web browsers have separate threads for
IO so the UI remains responsive
When Not to Create Threads

Some things really do need to happen in
sequence



Word processor, with its own thread for
printing… why not?
UI’s – have one GetMessage loop, with multiple
worker threads
Moral: Don’t use multiple threads just
because you can
Creating Threads



Once you’ve got one thread running (i.e.
you’ve executed your program) you can
start more
See MSDN for an example application
Based upon a thread function which gets
called, of form:

DWORD WINAPI ThreadFunc(PVOID
pvParam)
Caveat Emptor


Use Local variables in threads wherever you
can – static and global variables can be
modified at any time by other threads, leading
to all sorts of interesting race conditions
Your thread function must return a DWORD
value
CreateThread

HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
DWORD cbStack,
PTHREAD_START_ROUTINE pfnStartA
ddr,
PVOID pvParam,
DWORD fdwCreate,
PDWORD pdwThreadID);
Parms




psa: Security attributes – usually NULL if you
want the default
cbStack: The amount of stack space to
reserve; 0 gets you the default
pfnStartAddr: Pointer to the function to call to
start the thread
pvParam: Pointer to any parameters you wish
to pass
Bugs

DWORD WINAPI FirstThread(PVOID pvParam) {
// Initialize a stack-based variable
int x = 0;
DWORD dwThreadID;
// Create a new thread.
HANDLE hThread = CreateThread(NULL, 0, SecondThread, (PVOID) &x,
wThreadId);
// We don't reference the new thread anymore,
// so close our handle to it. CloseHandle(hThread);
// Our thread is done.
// BUG: our stack will be destroyed, but
//
SecondThread might try to access it.
return(0);
}
DWORD WINAPI SecondThread(PVOID pvParam) {
// Do some lengthy processing here.
// Attempt to access the variable on FirstThread's stack.
// NOTE: This may cause an access violation _ it depends on timing!
* ((int *) pvParam) = 5;
return(0);
}
0, &d
How to Solve this Problem


Hokey: create a static variable so the memory is
allocated away from the thread stack
Better: use proper thread synchronization techniques
– but that’s another story
Parms (cntd)


fdwCreate: 0 (get on with it) and
CREATE_SUSPENDED (create it paused).
See JobLab example for how to use this flag
pdwThreadID: the address of a DWORD in
which CreateThread stores the ID assigned to
the new thread
Terminating a Thread

Four ways:





The thread function returns (good)
The thread kills itself by calling ExitThread (bad)
Another thread calls TerminateThread (bad)
The process containing the thread terminates (bad)
Can use function to get exit code:

BOOL GetExitCodeThread(
HANDLE hThread,
PDWORD pdwExitCode);
Thread Startup
Thread Context




Each thread has its own set of CPU registers
Saved in a CONTEXT structure contained in
the thread’s kernel object
IP and SP are the most important
BaseThreadStart is called internally by the OS
BaseThreadStart




Sets up default SEH
System calls the function pointed to in
CreateThread, passing in pvParam
On Thread exit, return return code
If an exception is caught, handle it; this
involves terminating the entire process not
just the offending thread
C/C++ Considerations



Beware: You’re reading about how the OS
handles threads. Missing logical “sugar” when
considering the C/C++ RTLs
Read the MSDN section on threads – it’s very
useful!
Also: _beginthreadex
A Sense of Self

Threads can learn about themselves via:





HANDLE GetCurrentProcess()
HANDLE GetCurrentThread()
Return pseudo-handles not true unique identifiers
See also GetProcessTimes and GetThreadTimes
Can use DuplicateHandle to get a real handle to
the thread