Threads

< BACK  NEXT >
[oR]

Threads execute code. Each process starts out with a single primary thread that executes the entry point function (usually WinMain or the "C" main function). This thread can create secondary threads by calling the CreateThread function. Through thread scheduling, multiple threads appear to execute simultaneously. Only one thread can actually be running at a time, so the operating system gives each thread a small amount of processor time (called a quantum) based on a scheduling algorithm based on thread priorities.

Threads are created by applications to

  • Wait for some event to occur, such as termination of a process or receipt of information through a communications channel

  • Perform background processing, such as calculations or database querying

Additional threads are usually created to wait for an event to occur so the primary thread is not blocked (that is, waiting for an event to occur). If the primary thread is blocked, the application will not be able to redraw the user interface or respond to user input. In Listing 5.3 the primary thread was blocked through calling WaitForSingleObject, and the application would be unresponsive until the application started with CreateProcess terminates. This code could be improved by creating a secondary thread, and calling WaitForSingleObject on that thread. Techniques for doing this are described in the next sections of this chapter.

As it happens, most secondary threads are blocked waiting for an event to occur. They are not, therefore, consuming processor time. There are a few occasions when secondary threads are used to perform background processing. In this situation, a thread will be using processor time. Windows CE will not enter a power-saving state when a thread is executing, so care needs to be taken to ensure that such threads do not execute for too long.

Thread synchronization becomes an issue whenever you have more than two threads in an application. Synchronization techniques ensure that threads access shared resources in an ordered way and allow threads to communicate information to each other. Chapter 6 looks at synchronization techniques.

User-Interface and Worker Threads

There are two types of threads:

  • User-interface threads

  • Worker threads

A user-interface thread is capable of handling messages, so a user-interface thread can create windows. Each user-interface thread must have its own message loop to handle messages for windows created by that thread. An application's primary thread is a user-interface thread, and it will typically have a message loop.

A worker thread does not have a message loop and therefore cannot create windows. The thread can, however, send messages to a window handle created by a user-interface thread, and can display a message box using the MessageBox function.

While it is possible to have multiple user-interface threads in an application, it is rarely absolutely necessary. To keep application design simple, you should execute all user-interface code with the primary thread, and create secondary worker threads for any task that would, if executed on the primary thread, make the application unresponsive.

Threads do require memory and other resources and do take time to create. Therefore, you want to limit the number of threads that your application creates. Further, many threads can make your application design much more complex and introduce synchronization problems.

Accessing Global and Local Variables In Threads

Global or static variables are accessible by all threads in an application. Auto, or function-local variables, are placed on the thread's stack, and are therefore only accessible by the thread that calls the function. Synchronization techniques must be applied whenever more than one thread accesses a global variable. Synchronization techniques are not generally required when accessing auto variables on the stack.

Each thread has its own stack on which variables local to a function are placed. The maximum stack size in Windows CE is 58 KB. When a thread is created, Windows CE reserves a 60-KB region in the process's virtual address space and commits memory as the stack grows. If the stack cannot be grown (because of lack of physical memory), the thread will be suspended until the request can be granted. The number of threads that can be created is limited by the amount of free virtual memory address space in the process and the available physical memory.

Using Correct Thread Processing

You should be sure to write code that does not interfere with the Windows CE thread scheduler. If you do write such code, you can

  • Take up valuable processor time

  • Stop Windows CE from using power-saving techniques

A common mistake is to write a "while" loop to wait until some event (such as termination of a process) has completed, as shown in this pseudocode:

 while( ProcessHasNotFinished()) {   ; // do nothing } 

In fact, this while loop does lots! It repeatedly calls the function ProcessHasNotFinished, and has scheduled processor time to do this. While a thread is executing code Windows CE cannot enter into one of its power-saving states, and so battery power will be wasted. You can improve this code somewhat by putting the thread to sleep for a short while on each loop. This will reduce the amount of processor time taken up.

 while( ProcessHasNotFinished()) {   Sleep(100); // suspend thread for 100 milliseconds } 

However, the best solution is to use a function like WaitForSingleObject to block the thread until the process terminates. Then, the thread takes up no processor time and does not interfere with battery-saving routines.

Some desktop applications make use of idle time to do background processing using the primary thread. Modifying the standard message loop to use PeekMessage, as shown in the following pseudocode, does this.

 while(TRUE) {   if(PeekMessage(...))     {     // Call GetMessage, translate and     // dispatch message.     GetMessage(...);     DispatchMessage(...);     if(message is WM_QUIT)       break;     }   else     {     // do we have background processing?     if(bHaveBackgroundProcessing)       DoBackgroundProcessing();     } } 

This code, unfortunately, is not much better than the "while" loop, and it will take up processing time. The background processing should be carried out in a thread.


< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net