|
CSS 443 - |
Here are
the sample source codes on C++/Win32 threads we discussed in lectures.
Here
are some of the MSDN VC6.0 on: win32 thread programming and
on using the synchronization objects.
Explanation |
Source File (source only,
must download/compile to run) |
|
|
TthreadBase – Base for creation of new worker
threads. Here we see how _beginThread() can be used. The actual work is
performed in StupicThreadWorker (Yes, I can’t spell,
what other problems do you have? J) simulates working by sleeping. To See what is going on:
|
|
|
|
Same TthreadBase with added functionality
of fShouldTerminate. This allows external
control of determining if a thread should terminate. This time, we retain
main’s reference to the created threads (workThreads[] array), and let user decide which thread should
terminate. Notice, if we terminate main before the workThreads are properly
terminated (with _endThread()), all children threads will terminate
immediately! Results/Data from the worker thread may be lost! |
|
|
|
Simulate Priority: e.g. all student threads are running,
but as soon as they notice Kelvin thread starts, student threads should stop
and wait until Kelvin thread is done. How can we achieve this? We will use CEvent object to help us achieve
this. Relevant functions for CEvent: Set/Unset/Lock. Notice,
KelvinThread that chances are, when KelvinThread first started, studentThreads
are running also. When studentThread tries to get another job, they get
blocked, and have to wait for KelvinThread finish before they can do another
job. Another function implemented is, the TsyncObject accumulating TotalWorkTime, in this case we have one variable updated by multiple studentThreads, and we must protect the access of this variable. This is achieved by CMutex, to ensure only one thread has access to the variable. Notice in the code we simulate += with explicit variable transferring and sleep() to simulate delay. Try commend out the Mutex protection to see wrong answer resulting in total accumulated work time. |
|
|
|
Worker ID Thread: Finally something pseudo real: here we
have a system where we let the user choose which workThread gets to work on
each job. If a work is busy doing work, the main thread will be blocked,
otherwise, after assigning the work, the user can continue to the next job
assignment. Now how can we do this? We get an id
from the user and pass this id to all threads, the thread with the matching
id will erase the command, and go do the work. Besides protecting the id
(with CMutex) to make sure no two threads can change this at the same time,
we have two other synchronization tasks: 1.
All Worker Thread: should wait for command coming from
the main thread, and should not do anything while waiting. We will use a
CEvent (fNextCommandEvent) to achieve this. Initially, there is no “NextCommandEvent”,
so all workers will wait (stop at red-light). 2.
Next Command: after the main thread got a command, it
has to make sure the previous command has been read by the corresponding
worker thread. Here we will use another CEvent (fCommandReadEvent) to
synchronize our threads. Main thread resets this event, and the corresponding
thread will set this event. |
|
|
|
Print Thread: Lastly something relevant to our mp2, here
is using what we have learned from above to implement a simple printing
thread (based on my mp1 solution). No synchronization is attempted in this
example. This means, it is very easy to create undefined output. For example,
insert 1,2,3,4,5 and issue print command (started the print thread), now very
quickly, delete 2 from the linklist. Now what should the output of the print
command be (with or without the 2)? You see, it is important, that while a
thread is reading a list (to print it), no other thread should be allowed to
change the list (delete). |
|
|
|
|
|
|
|
CSS 443 Home |
Kelvin Sung |
CSS Home |
UW Bothell | UW Seattle
|
|
Last updated: January 2003 KS |