/home/wcbrown/courses/IC221/labs/L10/demo/goThe general setup here is this: Worm World itself is a library. Your program makes calls to Worm World API functions (
WWstart, WWmkworm,
WWmove,
and WWd2wall) to control one or more worms in
Worm World. I'm giving you a program that reads one color and
speed from the user via stdin, and controls a worm of that
color and at that speed via the Worm World API. Your job is
to modify the program so that the user can keep entering
colors and speeds and get more and more worms moving,
independently, around the screen. The way to do that is to
have each call to the work-control function run in a separate
thread!
/home/wcbrown/courses/IC221/labs/L10/lab10.tar.gzUnpack it, cd to the lab10 directory it creates, and make and run the program contained there. Give it input (via stdin)
red 30and see what happens.
pthread_create) to a function like
that returns void* and takes a single void* argument, like this:
void* foo(void *p);This means that any data that gets sent to the thread must be packaged up and referred to via void* pointer.
Your job is to modify the ic221.c file so that
main does not call wormctrl
directly, but instead calls a function with
prototype
void* wct(void *p);which, in turn, calls
wormctrl. Now, not only do
you need to define wct, but you need to figure
out how to get the color and delay parameters into
wct so it can pass them to wormctrl.
No global variables allowed! Here's how you do it:
wctparams that has two
fields, char color[32] and int
delay.
struct wctparams *pp and a) use malloc to set
pp to point to a new wctparams struct, and b) set the
color and delay fields of that object appropriately.
wct gets called, give it
the pointer pp, cast to a void*, as its
argument.
wct cast the parameter p
to a struct wctparams* object to retrieve
the color and delay values that wormctrl
needs.
Make sure the program compiles and runs, exactly like before.
wct
via pthread_create so that it actually runs in its own thread.
Be sure to put the whole read-input-call-wct thing in a loop
so you can create multiple worms. If you don't, you'll have
to at least call pause() at the end of main,
because when main exits the whole program, Worm World and all,
will exit. If the user hits end-or-file, you should be sure
to call pause() ... otherwise the whole Worm
World exits. Note that this is different from what would
happen in the Part 1 program if you hit end-of-file instead of
entering a color and delay value.
bash$ head -n 40 input.txt | ./go ← Just sends the first 40 lines of file to go
... where input.txt is one of the files you unpacked.
(If it just crashes put usleep(30000)
immediately after the call to pthread_create and
try again. This should at least stop the crashes.)
All hell breaks loose, right? What's going on? Are there simply
too many threads? Nope! The problem is that Worm World's API
functions: (WWstart, WWmkworm,
WWmove,
and WWd2wall)
are not thread safe! If more than one thread calls one of
these at the same time, bad things may happen. In other
words, any chunk of code that calls one of these functions is
a critical section and we need a mutex to protect
each of these. So your job is to:
pthread_mutex_t object.
pthread_mutex_lock
and pthread_mutex_unlock calls to ensure
mutual exclusion of these critical sections.
Now if you run this version of the program with the above
input, you should see the program run sanely with 40 worms!
In fact, it should be OK with up to 200 worms.
NOTE: If you put in the usleep(30000), you can
remove it now.