1 / 22

Win32 Programming

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

ranger
Download Presentation

Win32 Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Win32 Programming Lesson 9: Jobs & Thread Basics

  2. 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…

  3. 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

  4. Basic Idea • Create a Job Kernel Object • CreateJobObject • Place restrictions on the job object • SetInformationJobObject • Start up some processes… • CreateProcess • But, set CREATE_SUSPENDED flag • Assign processes to job • Start the primary thread of each process

  5. Termination • You can stop all processes in a job simply by terminating the Job Object • TerminateJobObject(HANDLE hJob, UInt uExitCode)

  6. 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

  7. 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!

  8. 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

  9. 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

  10. 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)

  11. 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

  12. CreateThread • HANDLE CreateThread(     PSECURITY_ATTRIBUTES psa,     DWORD cbStack,     PTHREAD_START_ROUTINE pfnStartAddr,     PVOID pvParam,     DWORD fdwCreate,     PDWORD pdwThreadID);

  13. 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

  14. 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,       0, &dwThreadId);     // 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); }

  15. 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

  16. 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

  17. 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);

  18. Thread Startup

  19. 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

  20. 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

  21. 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

  22. 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

More Related