Multithreading

In addition, many processes can contain multiple threads of execution. A thread is a lightweight process, meaning that it is similar to a process but shares resources such as global data with other threads. It is useful to think of the relationship between processes and threads as illustrated in Figure 2-1.

Figure 2-1 The relationship between processes and threads.

Each process contains some global information and at least one thread. In many respects, this single thread is no different from other threads that the application may generate. However, one significant difference exists: when the primary thread exits, the entire process ends (including any currently operating threads).

Although they are efficient, multiple-threaded programs are more difficult to create and debug than single-threaded programs. The reason is that in most cases, multiple single-threaded processes will not be operating on exactly the same resources at exactly the same time. This is precisely what multiple threads within a single process often need to do. For example, one or more threads might try to access a global variable at the same time.

Other problems exist as well. Imagine that the following brief code segment exists in a function that is called from multiple threads:

 //Aglobalvariable... externlongnumProcessed=0; //Functiondeclarations... voidDoInitialStuff(void); voidDoOtherProcessing(structTHING*thing); //Afunctioncalledbymultiplethreads... ProcessThing(structTHING*thing) { if(numProcessed==0) { DoInitialStuff(); } numProcessed++; DoOtherProcessing(thing); } 

We can see from the code that some initial processing must be done only once when the first object is processed . In isolation from other code operating at the same time, the DoInitialStuff function will run only once. However, with multithreaded programs, we cannot assume that code will operate in such isolation. Imagine two threads calling ProcessThing at about the same time. Normally, not more than one thing is happening at exactlythe same time (with symmetric multiprocessing [SMP] support, this is not always truemore on that later), but there is no assurance that each thread will perform ProcessThing as an atomic unit. So given two threads calling ProcessThing , the following order of execution is possible:

Thread 1 Thread 2
 1.if (numProcessed==0) (Evaluates TRUE) 
 
 
 2.if (numProcessed==0) (Evaluates TRUE) 
 3.DoInitialStuff(); (Do work that should be done only once) 
 
 
 4.DoInitialStuff(); (Do work that should be done  only once) 

SMP machines create a more complex situation with a much smaller margin of error. Given more than one processor, an SMP operating system such as Windows 2000 will actually execute more than a single instruction at the same instant. In the previous case, the calls to check on the number of records processed or the calls to DoInitialStuff could happen at exactly the same instant.

The previous example presumes global variables; however, these variables do not need to be of truly global scope. They could be static members of a class, or perhaps even other types of resources. For instance, some code might operate under the assumption that it is safe to write to and read from a file local to the system in which the operation is taking place (for example, an INI file located in the Windows directory). This might have been a reasonable assumption in the past if the program ensured that only a single instance of itself was running. Given the multithreaded scenario, it is not sufficient to ensure that a single instance of the program is running. Of course, other problems with this kind of model exist as well, and examples less contrived than this one abound. What programmers need is some way to coordinate the sharing of resources among multiple threads and processes.



Inside Server-Based Applications
Inside Server-Based Applications (DV-MPS General)
ISBN: 1572318171
EAN: 2147483647
Year: 1999
Pages: 91

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