I just finished the final project for GIOS (Graduate Introduction to Operating
Systems), writing a couple dozen lines of
C to implement a client and a
multithreaded server that processes RPC (remote procedure call); client sends a
jpeg to the server and the server downsamples it to a lower resolution. As
mentioned in my previous post, prior to working on this project, I only had a
(very) vague and loose idea of RPC.
Anyways, while I enjoyed the project and got to peek under the hood of how RPC
and XDR work, there was a very brief moment where I temporarily lost my sanity.
For about 3 hours, I could not for the life of me figure out why my
multi-threaded code was behaving so sporadically; to debug the issue, I
sprinkled about a dozen or so
fprintf statements, each one including the
thread id. But I was going no where.
But after forcing myself to step away from my computer for several hours, I was able to look at the code with a fresh pair of eyes. And when I launched the terminal and pulled up the code in vim, the solution practically jumped out at me: my threads were waiting on semaphores that were uninitialized. More specifically, my main thread declared the semaphores, launched the worker threads (which were waiting on the semaphores), and then initialized the semaphores. After fixing this, which literally moving 8 liness of code a few liens up, my code started behaving as expected.
In short: never forget to initialize your semaphores BEFORE launching your worker threads. If you do forget, you’re gonna have a bad time.