Productor Consumidor 01 — Transcript
Full transcript
- 0:00Good morning and welcome to this new
- 0:03operating systems class. The
- 0:07bibliographic reference for this class
- 0:10is the book Operating System Concepts
- 0:13by Silberschatz, chapter 6, process
- 0:16synchronization. Well, on page 171 we
- 0:20see the producer's pseudocode. The
- 0:24producer is a process that produces
- 0:26data in a shared memory area. The
- 0:30function starts with "in" equal to zero
- 0:32. "In" is a producer variable that
- 0:34indicates which buffer position the
- 0:36data should be placed in, and then it
- 0:38enters an infinite cycle, "while true,"
- 0:40in an infinite production cycle. The
- 0:43first line of code in the "while true"
- 0:46is "while counter equals buffer size
- 0:49semicolon." That is a control so the
- 0:52producer does not produce or stops
- 0:55producing when the number of elements
- 0:59it produced, the number of elements in
- 1:02the buffer, is equal to the number of
- 1:05elements the buffer can hold. Otherwise
- 1:10, if the producer produces, it could
- 1:12destroy data that has not yet been
- 1:14consumed. Then comes the produce
- 1:17function, which generates data and
- 1:20places it in the buffer or in the
- 1:22shared memory. At the "in" position,
- 1:25after "counter equals counter plus one,
- 1:28" the producer records that it just
- 1:30produced an element. So the counter
- 1:34counts the number of elements that are
- 1:36produced. And in the last line of the
- 1:40infinite cycle, a new value is assigned
- 1:43to "in" so it points to the next buffer
- 1:46position so the producer can produce in
- 1:49a consecutive memory area. Here we see
- 1:55the consumer's pseudocode. The consumer
- 1:58process is the process that consumes
- 2:01the data produced by the producer. The
- 2:04code is quite similar. Notice that it
- 2:07starts with the "out" variable equal to
- 2:09zero. The zero variable in the, sorry,
- 2:13the "out" variable in the consumer
- 2:15indicates to the consumer at which
- 2:17buffer position it has to consume. From
- 2:19which buffer position it has to consume
- 2:21. Then it starts or enters a "while
- 2:24true," an infinite consumption cycle
- 2:26where the first instruction of the
- 2:28infinite cycle is "while counter equals
- 2:31zero semicolon." This is the control
- 2:35the consumer has so that when it has
- 2:37consumed all the production, it stops
- 2:39consuming. Yes, because otherwise it
- 2:42would be consuming already consumed
- 2:44elements or it would be consuming
- 2:46garbage from the buffer. Then, in the
- 2:50line "element equals buffer out," that
- 2:52"element" is a local consumer variable
- 2:55and takes the element it consumes from
- 2:58the "out" position of the shared memory
- 3:01called buffer. Next, on the following
- 3:06line, counter equals counter minus 1.
- 3:08There the counter, sorry, the consumer
- 3:11registers that it has consumed an item,
- 3:14so it subtracts it from the number of
- 3:16items in the buffer, and the last
- 3:18consumer line is sale equals sale + 1,
- 3:21modulo buffer size. This modifies the
- 3:25value of "sale" so that it points to
- 3:28the next position in the buffer from
- 3:30where the consumer has to consume the
- 3:33item. Here we highlight the shared
- 3:39memory resources used to be able to
- 3:42carry out the producer-consumer process
- 3:45. One shared memory area is the buffer,
- 3:50which is where the producer will place
- 3:53the production and from where the
- 3:55consumer will take the produced data.
- 3:58And the other shared memory resource is
- 4:01the counter. The counter will store the
- 4:04number of elements that actually exist
- 4:07in the buffer. For example, when
- 4:09producer-consumer starts, counter is
- 4:12equal to zero. The buffer is empty.
- 4:16Then, when the producer produces an
- 4:18item, counter will be equal to one and
- 4:21there will be one item in position zero
- 4:23of the buffer. Let's assume it's a
- 4:27production of letters of the alphabet
- 4:31and that they can be stored with a
- 4:33maximum of five letters in the buffer.
- 4:38Yes? What does that mean? That when
- 4:40counter is equal to 5, then the
- 4:42producer cannot produce, and when
- 4:45counter is equal to 0, the consumer
- 4:47cannot consume. We highlight in the
- 4:51image that the counter is 4 bytes
- 4:53because it will be a short integer that
- 4:56will require 4 bytes, and the buffer
- 4:58will require 5 bytes because it will
- 5:01store one character in each position.
- 5:06Well, here we highlight the local data
- 5:09or local variables of the producer
- 5:12process and the consumer process. The
- 5:16two most important local variables to
- 5:18highlight are the "pone"(put) variable
- 5:21in the producer and the "sale"(get)
- 5:23variable in the consumer. The "pone"
- 5:26variable in the producer indicates at
- 5:29which position of the buffer, or at
- 5:32which shared memory offset, the
- 5:34producer will store the produced
- 5:37character; and the "sale" variable in
- 5:40the consumer will indicate from which
- 5:43position of the buffer, or from which
- 5:46memory area location, the consumer will
- 5:49take the data or character produced by
- 5:52the producer. Well, one of the most
- 5:56important characteristics of the buffer
- 5:58is that this buffer will be a circular
- 6:01buffer. What does this mean? We already
- 6:04said that our buffer has the storage
- 6:06capacity for five characters. So, the
- 6:09first character will be positioned at
- 6:12index zero, the second character at
- 6:14index one, the third character at index
- 6:17two, the fourth character at index
- 6:19three, and the fifth character at index
- 6:21four. This means the "put" pointer will
- 6:25have to indicate from position 0 to
- 6:28position 4, passing through the values
- 6:310, 1, 2, 3, and 4. But since it is
- 6:35circular, when the producer has to
- 6:38produce again, it will go back to
- 6:40producing at position zero. So, what
- 6:44would the production cycle be like with
- 6:47respect to the "put" variable? In this
- 6:51case, it would have to take the values
- 6:540, 1, 2, 3, 4, then it would take the
- 6:57values 0, 1, 2, 3, 4 again, and then it
- 7:00would take the values 0, 1, 2, 3, 4
- 7:02once more. This means that when the
- 7:06buffer is full and the consumer
- 7:09consumes, the producer will start
- 7:12producing again at position zero of the
- 7:16buffer. What allows this is "put"
- 7:20equals "put" plus one modulo buffer
- 7:23size. The same applies to the consumer.
- 7:28Well, this is the code written in C
- 7:31language under a Debian Linux operating
- 7:34system, the code that allows us to
- 7:36create the shared memory area for the
- 7:39buffer and the shared memory area for
- 7:42the counter. We are not going to go
- 7:46into detail about this code; we will
- 7:48simply comment on its most general
- 7:50characteristics. On lines 10 and 11, we
- 7:55write the system calls to create shared
- 7:59memory. Line 10 contains the system
- 8:03call to create the shared memory area
- 8:07for the buffer, and line 11 contains
- 8:10the system call to create the shared
- 8:13memory for the counter. We will
- 8:19highlight from these two system calls
- 8:22nothing more than the constant 5 of the
- 8:26system call on line 10. Where 5
- 8:31indicates the number of bytes that we
- 8:34are going to request for the buffer.
- 8:37Remember that the producer was going to
- 8:39write five characters, so we are going
- 8:42to need 5 bytes. And on line 11, the "
- 8:45sizeof" is requesting shared memory for
- 8:49the counter for a short integer. And
- 8:52the system will give us 4 bytes, and on
- 8:56lines 13 and 14, we simply show the
- 8:59result of the execution of the system
- 9:02calls from line 10 and line 11. If we
- 9:07see a minus one on the screen when we
- 9:10execute this program in either shared
- 9:13memory buffer, or memory counter, or
- 9:15both, it means the system calls failed.
- 9:20If we see a number greater than -1, it
- 9:23means the system calls on lines 10 and
- 9:2711 were successful, and our shared
- 9:29memory is now created so that the
- 9:32producer and consumer can use it later.
- 9:38We edit the source program we just saw
- 9:47right there. Uh, from the operating
- 9:50system command line, we are going to
- 9:51compile the program. We compile it
- 9:55there, and we will check the
- 9:57inter-process communication and
- 9:59synchronization resources using the
- 10:01IPCS command. We are interested in the
- 10:04shared memory segments. Those ones
- 10:07there are used by the system, the ones
- 10:09you see. Now, what we are going to do
- 10:13is run the program to create the shared
- 10:16memory areas, and we see that as a
- 10:18result of the execution, the numbers we
- 10:21see there are greater than -1. That
- 10:24means the resources were created
- 10:26successfully. We see them there. Uh, in
- 10:29the bytes column, we can see five and
- 10:32four, which are the number of bytes
- 10:34that were created by the system. Here
- 10:39we see a small walkthrough of the
- 10:41producer and the consumer. The producer
- 10:44is producing into the buffer at the
- 10:46position indicated by 'put'. After
- 10:49producing, it increments the 'put'
- 10:51position and counts that there is one
- 10:53production. There, the producer again
- 10:57produces at the position indicated by '
- 11:00put', increments the 'put' position,
- 11:03and increments the value of the
- 11:05quantity of products. In the buffer,
- 11:09the producer produces at the position
- 11:12indicated by 'put', increments the 'put
- 11:14' position, and increments the value
- 11:17indicating the number of productions in
- 11:19the buffer. Here the consumer comes
- 11:23into action, consumes from the position
- 11:25where it says 'get', the consumer
- 11:27increments the 'get' position and also
- 11:30updates the counter value to two
- 11:32productions in the buffer. Now, again,
- 11:36the producer produces at the position
- 11:38indicated by 'put', increments the 'put
- 11:41' position, and also updates the
- 11:44counter value with three productions in
- 11:46the buffer. The producer produces one
- 11:50more element at the position indicated
- 11:53by 'put' and increments it. Well,
- 11:56actually, now since the buffer is
- 11:58circular, the 'put' value goes to zero
- 12:01so that the producer starts producing
- 12:03again from position zero and updates
- 12:08the counter to four productions in the
- 12:10buffer. The consumer consumes from the
- 12:14position indicated by 'get', updates
- 12:17the 'get' value, and says, "There are
- 12:19three productions in the buffer." The
- 12:23consumer consumes from the position
- 12:25indicated by 'get', updates the 'get'
- 12:27value, and indicates that there are two
- 12:30productions in the buffer. The consumer
- 12:32consumes from the position indicated by
- 12:35'get', increments the 'get' value, and
- 12:37says, "There is one production in the
- 12:39buffer." The consumer consumes from the
- 12:43position indicated by "out," and now "
- 12:45out" takes the value of zero because
- 12:48the next consumption must be done by
- 12:51the consumer from position zero, and it
- 12:53updates the counter indicating the
- 12:56buffer is empty. Well, here we see how
- 13:01we have initialized the buffer shared
- 13:03memory and the counter shared memory.
- 13:07Although it is not necessary to
- 13:09initialize the buffer shared memory
- 13:12because the consumer cannot consume if
- 13:14there is no production, and the
- 13:17producer, when producing, will
- 13:19overwrite the information that was
- 13:22previously in that position. However,
- 13:27it is very important to initialize the
- 13:29counter shared memory area because, at
- 13:32the moment of creating the counter
- 13:34shared memory area, there is not
- 13:36necessarily a zero there, so there
- 13:38could be garbage data. So, we do have
- 13:42to initialize the counter shared memory
- 13:45area to zero, indicating that the
- 13:47buffer is empty. Here we see the C code
- 13:52we have written to initialize the
- 13:55shared memory areas. I will not go into
- 13:59details regarding the code. The only
- 14:03thing I want to highlight is that it is
- 14:06not necessary to initialize the buffer
- 14:09shared memory, but it is very important
- 14:12and necessary to initialize the shared
- 14:15memory that will store the number of
- 14:17elements in the buffer, that is, the
- 14:20counter, initializing it to zero. You
- 14:24can see there on line 22 how we have
- 14:27placed a zero in the counter shared
- 14:30memory area. Here we see the code for
- 14:35the producer process. It is a fairly
- 14:38simple code. It has a production
- 14:41function that produces a character, a
- 14:44letter of the alphabet from A to Z. And
- 14:47we have the part highlighted in yellow,
- 14:50which is the part that implements the
- 14:53pseudocode shown at the beginning of
- 14:56these slides and which is shown in the
- 14:59Silberschatz book at the beginning of
- 15:02chapter 6. On line 27, you can see the
- 15:08loop that ensures the producer cannot
- 15:11produce if the buffer is full. On line
- 15:1728, the production is assigned to the "
- 15:19in" position within the buffer. On line
- 15:2429, the number of productions is
- 15:26incremented by one. On line 30, well,
- 15:30what the producer has produced is shown
- 15:33on the screen, and on line 31, the
- 15:36value of "in" is updated to point to
- 15:38the next position in the buffer or to
- 15:41point to position zero of the buffer.
- 15:46Here we see the code for the consumer
- 15:48process. We have also presented it in
- 15:50the simplest way possible. The part
- 15:54that implements the pseudocode is
- 15:57between lines 23 and 30. There we see
- 16:02it, we see it highlighted there. On
- 16:04line 25, the consumer process checks
- 16:07that it does not consume if the buffer
- 16:10is empty. Line 26 indicates that a
- 16:15consumption is going to be performed,
- 16:17subtracting one from the counter. Line
- 16:2227 shows what is being consumed, and
- 16:25line 28 updates the exit position to
- 16:29the next buffer position or to position
- 16:33zero. Here we see how the
- 16:36producer-consumer works. We run the
- 16:39producer, which blocks because the
- 16:41buffer is full. We run the consumer,
- 16:44and consumption and production begin.
- 16:48We stop the consumer, and the producer
- 16:50gets blocked by a full buffer. We
- 16:53restart the consumer, and here we stop
- 16:55the producer to see how the consumer
- 16:58blocks due to an empty buffer. There we
- 17:02restart the producer, and production
- 17:04and consumption continue infinitely.
- 17:08Well, so far no problems; everything
- 17:11worked perfectly. So, what is the real
- 17:14problem with the producer-consumer? The
- 17:18problem lies in the operation the
- 17:21producer performs when it adds one to
- 17:24the shared memory area of the counter,
- 17:27and the operation the consumer performs
- 17:30when it subtracts one from it. Why? The
- 17:34addition operation is carried out in
- 17:37three low-level operations. The first
- 17:42operation is to take the content from
- 17:44the counter memory area to the
- 17:45processor's accumulator register. The
- 17:48second operation is to add one to the
- 17:51processor's accumulator register and
- 17:54leave the result in that register. And
- 17:57the third operation is to take the
- 17:59result from the accumulator register to
- 18:01the shared memory area of the counter.
- 18:04In the consumer process, exactly the
- 18:06same thing happens. The only difference
- 18:09is that one is subtracted from the
- 18:11shared memory area of the counter.
- 18:14Let's do a small desk check. For
- 18:17example, if the counter is four, it
- 18:19means there are four elements in the
- 18:21buffer. So, if from here a production
- 18:27and a consumption are performed, the
- 18:30counter value should remain four. Well,
- 18:35here is the problem. Let's begin.
- 18:38Suppose the processor is assigned to
- 18:40the producer; the producer takes the
- 18:41value four from the shared memory area
- 18:43and assigns it to the accumulator. Then
- 18:47the producer adds one to that value in
- 18:50the accumulator and obtains the value
- 18:52five in the accumulator. Here the
- 18:55producer process is interrupted by the
- 18:58operating system. Then we give the
- 19:01processor to the consumer. The consumer
- 19:04takes what is in the counter memory,
- 19:06which is a four, and subtracts one from
- 19:09that value, so it gets a three in the
- 19:11accumulator. At this moment, the
- 19:14operating system interrupts the
- 19:17consumer's execution and returns the
- 19:19CPU to the producer. So, the producer
- 19:23has a value of five in the accumulator
- 19:25and passes that value of five to the
- 19:27memory address corresponding to the
- 19:29shared memory area of the counter,
- 19:31leaving a value of five. Then the
- 19:33processor is taken from the producer
- 19:35and given to the consumer, the same
- 19:37thing happens with the consumer, and it
- 19:40leaves a value of three. This means
- 19:42that in the shared memory area, a value
- 19:45of C or a value of 3 will remain, when
- 19:48it should have actually been a value of
- 19:50four. This problem we just described
- 19:55has a name; it is a classic problem in
- 19:58inter-process communication and
- 20:01synchronization systems, and it is
- 20:04called the critical section problem.
- 20:09Alright, in the next class, we will see
- 20:12how to solve this problem. Well, thank
- 20:18you very much for your attention on
- 20:19behalf of operating systems. I hope
- 20:23this video is helpful, and we will see
- 20:25you soon in the next presentation.
- 20:28Thank you very much. Good day. See you
- 20:30later.
About this transcript
This page contains the full transcript of Productor Consumidor 01 by juancarlosjromer, generated from the public captions YouTube serves with the video. The transcript has 2,698 words across 410 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.