COMP3000 Operating Systems F23: Tutorial 6: Difference between revisions
Created page with "In this tutorial you will be learning about two implementations of the [https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem producer-consumer problem], a classic example of a concurrency problem. The [http://pages.cs.wisc.edu/~remzi/OSTEP/ class textbook] covers concurrency in great detail in Chapters 25-34, and the producer-consumer problem is covered in [http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf Chapter 30 (Condition Variables)] and [http://pages..." |
|||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
In this tutorial you will be learning about two implementations of the [https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem producer-consumer problem], a classic example of a concurrency problem. The [http://pages.cs.wisc.edu/~remzi/OSTEP/ class textbook] covers concurrency in great detail in Chapters 25-34, and the producer-consumer problem is covered in [http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf Chapter 30 (Condition Variables)] and [http://pages.cs.wisc.edu/~remzi/OSTEP/threads-sema.pdf Chapter 31 (Semaphores)]. While you can look at this part of the textbook, note that we will not be covering this material in the same level of detail, as should be clear from this tutorial. | In this tutorial you will be learning about two implementations of the [https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem producer-consumer problem], a classic example of a concurrency problem. The [http://pages.cs.wisc.edu/~remzi/OSTEP/ class textbook] covers concurrency in great detail in Chapters 25-34, and the producer-consumer problem is covered in [http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf Chapter 30 (Condition Variables)] and [http://pages.cs.wisc.edu/~remzi/OSTEP/threads-sema.pdf Chapter 31 (Semaphores)]. While you can look at this part of the textbook, note that we will not be covering this material in the same level of detail, as should be clear from this tutorial. | ||
==A: Getting Started== | ==A: Getting Started== | ||
Download [https://people.scs.carleton.ca/~ | Download [https://people.scs.carleton.ca/~abdou/comp3000/f23/tut6/3000pc.zip 3000pc.zip], unpack, and run <code>make</code> to compile <code>3000pc-fifo</code> and <code>3000pc-rendezvous</code>. | ||
Try to take this opportunity to read and understand the two programs line by line. | Try to take this opportunity to read and understand the two programs line by line. | ||
Line 29: | Line 12: | ||
# Run both programs with the same arguments of your choice. Do this a few times with different arguments. Do they behave the same way? Do you notice <u>any differences</u>? (again, no “correct” answers but just play with them and document your observations) | # Run both programs with the same arguments of your choice. Do this a few times with different arguments. Do they behave the same way? Do you notice <u>any differences</u>? (again, no “correct” answers but just play with them and document your observations) | ||
# Repeat the above experiment, this time running each program under < | # Repeat the above experiment, this time running each program under <code>strace</code> (with the <code>-f</code> flag to trace children too). Do you notice any difference in the system calls each program makes? Remember to ignore the lines before <code>main()</code> that might be distracting, e.g., start looking around and after the <code>clone()</code> system call. | ||
# You can see there is "< | # You can see there is "<code>#define QUEUESIZE 32</code>" in both programs. Are they actually used? <u>Why (not)</u>? | ||
==B: Producer/Consumer with Pipes== | ==B: Producer/Consumer with Pipes== | ||
<ol style="list-style-type:decimal"> | <ol style="list-style-type:decimal"> | ||
<li> Examine the source code of < | <li> Examine the source code of <code>3000pc-fifo</code>. Pay attention to the call to <code>pipe(pipefd)</code> on line 192 and make the connection with what has been discussed in the lecture (also look at the man page for <code>pipe(2)</code>). Explain the following: | ||
<ol style="list-style-type:lower-alpha"> | <ol style="list-style-type:lower-alpha"> | ||
<li> How does the consumer receive words to consume? </li> | <li> How does the consumer receive words to consume? </li> | ||
<li> How does the producer generate and send words to the consumer? </li> | <li> How does the producer generate and send words to the consumer? </li> | ||
<li> Why is the call to < | <li> Why is the call to <code>srandom(time(NULL))</code> on line 169 necessary? </li> | ||
</ol> | </ol> | ||
</li> | </li> | ||
<li> Replace the call to < | <li> Replace the call to <code>srandom(time(NULL))</code> on line 169 with <code>srandom(42)</code>. What differences do you notice in <code>3000pc-fifo</code>'s behavior? </li> | ||
</ol> | </ol> | ||
==C: Producer/Consumer with Shared Memory== | ==C: Producer/Consumer with Shared Memory== | ||
<ol style="list-style-type:decimal"> | <ol style="list-style-type:decimal"> | ||
<li> Examine the source code of < | <li> Examine the source code of <code>3000pc-rendezvous</code>. Explain the following: | ||
<ol style="list-style-type:lower-alpha"> | <ol style="list-style-type:lower-alpha"> | ||
<li> What are a few ways that < | <li> What are a few ways that <code>3000pc-rendezvous</code> is different from <code>3000pc-fifo</code>? </li> | ||
<li> What does the call to < | <li> What does the call to <code>mmap()</code> on line 347 do (compared to our previous uses of <code>mmap()</code>)? <u>How</u> did you figure this out? </li> | ||
<li> How does the producer notify the consumer that the queue is no longer empty? </li> | <li> How does the producer notify the consumer that the queue is no longer empty? </li> | ||
<li> How does the consumer notify the producer that the queue is no longer full? </li> | <li> How does the consumer notify the producer that the queue is no longer full? </li> | ||
Line 56: | Line 39: | ||
<li> What arguments can you provide to make the producer wait for the consumer? Hint: Check the size of the queue. </li> | <li> What arguments can you provide to make the producer wait for the consumer? Hint: Check the size of the queue. </li> | ||
<li> What arguments can you provide to make the consumer wait for the producer? (You can disregard the wait at the very beginning as the queue is initially empty) </li> | <li> What arguments can you provide to make the consumer wait for the producer? (You can disregard the wait at the very beginning as the queue is initially empty) </li> | ||
<li> Another student tells you that the difference between processes and threads is that processes never share memory, while threads do. Is this statement correct or incorrect? How can the behavior of < | <li> Another student tells you that the difference between processes and threads is that processes never share memory, while threads do. Is this statement correct or incorrect? How can the behavior of <code>3000pc-rendezvous</code> help justify your answer? </li> | ||
<li> Change the calls to < | <li> Change the calls to <code>pthread_mutexattr_setpshared()</code> and <code>pthread_condattr_setpshared()</code> (lines 293 and 298) to take 0 instead of 1. How does the behavior or <code>3000pc-rendezvous</code> change? Does anything break? </li> | ||
</ol> | </ol> |
Latest revision as of 01:09, 25 October 2023
In this tutorial you will be learning about two implementations of the producer-consumer problem, a classic example of a concurrency problem. The class textbook covers concurrency in great detail in Chapters 25-34, and the producer-consumer problem is covered in Chapter 30 (Condition Variables) and Chapter 31 (Semaphores). While you can look at this part of the textbook, note that we will not be covering this material in the same level of detail, as should be clear from this tutorial.
A: Getting Started
Download 3000pc.zip, unpack, and run make
to compile 3000pc-fifo
and 3000pc-rendezvous
.
Try to take this opportunity to read and understand the two programs line by line.
- Note that these programs take 3 arguments each:
- The number of events to process
- The number of events to produce before the producer sleeps for 1 second
- The number of events to consume before the consumer sleeps for 1 second
- Note that these programs take 3 arguments each:
- Run both programs with the same arguments of your choice. Do this a few times with different arguments. Do they behave the same way? Do you notice any differences? (again, no “correct” answers but just play with them and document your observations)
- Repeat the above experiment, this time running each program under
strace
(with the-f
flag to trace children too). Do you notice any difference in the system calls each program makes? Remember to ignore the lines beforemain()
that might be distracting, e.g., start looking around and after theclone()
system call. - You can see there is "
#define QUEUESIZE 32
" in both programs. Are they actually used? Why (not)?
B: Producer/Consumer with Pipes
- Examine the source code of
3000pc-fifo
. Pay attention to the call topipe(pipefd)
on line 192 and make the connection with what has been discussed in the lecture (also look at the man page forpipe(2)
). Explain the following:- How does the consumer receive words to consume?
- How does the producer generate and send words to the consumer?
- Why is the call to
srandom(time(NULL))
on line 169 necessary?
- Replace the call to
srandom(time(NULL))
on line 169 withsrandom(42)
. What differences do you notice in3000pc-fifo
's behavior?
- Examine the source code of
3000pc-rendezvous
. Explain the following:- What are a few ways that
3000pc-rendezvous
is different from3000pc-fifo
? - What does the call to
mmap()
on line 347 do (compared to our previous uses ofmmap()
)? How did you figure this out? - How does the producer notify the consumer that the queue is no longer empty?
- How does the consumer notify the producer that the queue is no longer full?
- What are a few ways that
- What arguments can you provide to make the producer wait for the consumer? Hint: Check the size of the queue.
- What arguments can you provide to make the consumer wait for the producer? (You can disregard the wait at the very beginning as the queue is initially empty)
- Another student tells you that the difference between processes and threads is that processes never share memory, while threads do. Is this statement correct or incorrect? How can the behavior of
3000pc-rendezvous
help justify your answer? - Change the calls to
pthread_mutexattr_setpshared()
andpthread_condattr_setpshared()
(lines 293 and 298) to take 0 instead of 1. How does the behavior or3000pc-rendezvous
change? Does anything break?