pipes 1 — Transcript
Full transcript
- 0:01Good morning. Welcome to this new video
- 0:05on operating systems. In it, we will
- 0:08try to show or introduce pipe
- 0:10programming. This video consists of
- 0:14three parts. The first part is a basic
- 0:17theoretical introduction with some
- 0:19simple examples. The second part is the
- 0:22presentation of an example problem, and
- 0:25the third part is the solution to the
- 0:27example problem. Well, let's get
- 0:30started. Introduction to pipe
- 0:36programming. One of the simplest forms
- 0:40of communication between related
- 0:43processes is unnamed pipes, also called
- 0:46unnamed pipes, whose system call to
- 0:49create the resource is in pipe and we
- 0:52pass it as an argument a vector of
- 0:55integers used between related processes
- 0:58, which are processes created with the
- 1:01FOR system call, which creates a
- 1:04relationship between a parent process
- 1:06and a child process. This system call
- 1:10causes the child process to inherit the
- 1:12descriptors of the pipe communication
- 1:14resource created by the parent process.
- 1:18The pipe is an area of memory where
- 1:20processes can write and read in a fifo
- 1:23order, thus allowing communication. In
- 1:29all the code examples, we assume that
- 1:31the functions that are executed never
- 1:33fail. We do this to reduce the
- 1:36complexity of the code and focus on
- 1:38pipe handling. Here we see a very
- 1:45simple example of a process that
- 1:48creates a pipe, creates a child, and
- 1:50both the parent and child display the
- 1:56read and write descriptors that can be
- 1:59used to read from and write to the pipe
- 2:02. Pipes are best known for their use
- 2:07from the shell command line, where
- 2:10processes are connected through a pipe
- 2:12and data flow is in one direction, as
- 2:15shown in the following command line,
- 2:17where the pipe is the vertical bar. The
- 2:22LS process writes its output to the
- 2:25pipe. The SOR process reads its input
- 2:29from the pipe and writes its output to
- 2:31another pipe, and the GRP command reads
- 2:33its input from the pipe and writes its
- 2:36output to the screen. To connect two or
- 2:43more processes through a pipe, we have
- 2:46to create a pipe before a process
- 2:48creates a child process, since the
- 2:50child inherits the table of open file
- 2:53descriptors from the parent, and will
- 2:56also inherit the copy of the
- 2:57descriptors associated with the pipe.
- 3:03Establishing communication between
- 3:05processes using pipes is quite simple,
- 3:08since pipes provide a layer of
- 3:10synchronization of locks in writing and
- 3:13reading, meaning that the programmer
- 3:15does not have to include codes for
- 3:18synchronization in the communication
- 3:20between two processes. A process
- 3:25writing to the pipe can fill the pipe
- 3:27and another process reading the pipe
- 3:29can change the pipe, since reading from
- 3:31the pipe is destructive. In these cases
- 3:35, when the pipe is full, the writer
- 3:37magically blocks writing and when the
- 3:40pipe is empty, the reader magically
- 3:43blocks reading as well. Of course, for
- 3:47this to happen, certain conditions must
- 3:49be met, which we will see later. If we
- 3:54add to this that reading from the pipe
- 3:56is destructive, allowing the pipe to be
- 3:58used in such a way that it never
- 4:00exhausts its storage capacity and that
- 4:03reading is done in the same order in
- 4:05which it was written to the pipe, all
- 4:07this makes communication very efficient
- 4:09with very little programming. Of course
- 4:14, we must have a great command of the
- 4:17pipe in programming so that deadlocks
- 4:20do not occur. First, it must be taken
- 4:24into account that although a P allows
- 4:26many processes to write to it and many
- 4:28processes to read from it concurrently,
- 4:30the most appropriate thing would be to
- 4:33have only one writer and one reader on
- 4:35a pipe at a given time. This will avoid
- 4:39unwanted deadlocks. Something to keep
- 4:42in mind is that pipes only allow
- 4:44related processes to communicate. We
- 4:47can say that related processes are
- 4:50those that are created using a fork and
- 4:52that have a parent-child relationship.
- 4:56Let's do an example of a reader process
- 4:59and a writer process using a pipe. The
- 5:02diagram shows a parent process writing
- 5:05to a pipe and a child process reading
- 5:07from a pipe. Here we have the code and
- 5:12we can see on line seven the definition
- 5:15of the child variable of type PIT T on
- 5:19line 8 or the declaration of the vector
- 5:22of two integers to store what the pipe
- 5:25system call returns. On line nine we
- 5:30execute the pipe system call passing it
- 5:33as an argument the vector p of two
- 5:36integers. On line 10 we create the
- 5:39child. On line 11 we ask if the Fork
- 5:43system call returned -1, then it could
- 5:46not create the child and we return the
- 5:49yel -2. On line 12 we ask if we are in
- 5:53the execution of the child. If we are
- 5:57in the execution of the child, the
- 6:00child closes the write descriptor
- 6:02because it will only read and displays
- 6:05the values of the file descriptors. On
- 6:09line 18 the execution of the parent
- 6:13begins. The parent closes its reading
- 6:16channel because it will only write and
- 6:19also displays the pipe descriptors
- 6:21obtained from the pipe system call. It
- 6:25is important to highlight the close P1
- 6:27instruction in the child process and
- 6:30the close P0 instruction in the parent
- 6:32process, since this specifies that
- 6:34there is only one reader process and
- 6:37one writer process. Otherwise, we could
- 6:40end up with problems or some type of
- 6:43deadlock. Well, here we are going to
- 6:46show two reader processes and two
- 6:48writer processes. Although only one
- 6:51parent process and one child process
- 6:53are shown, it is important to note that
- 6:55there are two writers and two readers.
- 6:58This means that each process fulfills
- 7:00the function of writer and reader at
- 7:02the same time. The diagram shows how
- 7:06the parent process writes and reads and
- 7:09how the child process also writes and
- 7:11reads. It is important to note that
- 7:14writing is done through the same end
- 7:17and reading is also done through the
- 7:19same end. This is represented in the C
- 7:23code by the descriptors. This means
- 7:26that there is a descriptor for writing
- 7:28and whenever something is written, it
- 7:30will be written to that descriptor and
- 7:32there is only one descriptor for
- 7:34reading and whenever something is read,
- 7:36it will be read from that descriptor.
- 7:39Unlike the previous code, this code
- 7:41does not include the close in the child
- 7:44process and does not include the close
- 7:47in the parent process. This makes the
- 7:50big difference that in this code we
- 7:53have two processes: writers and two
- 7:56reader processes. It is important to
- 8:00note that communication in pipes is
- 8:03unidirectional or half-duplex. This
- 8:06means that writing is done through file
- 8:09descriptor 1 and always reading is done
- 8:12through file descriptor 2. What happens
- 8:14to a writer process when it tries to
- 8:16write to a full pipe? A writer process
- 8:21tries to write the alphabet in the pipe
- 8:24many times and blocks when the pipe is
- 8:26full. In this case, the only process is
- 8:31a writer and a reader. By default, when
- 8:35a pipe is created, the process or
- 8:37processes that obtain the read and
- 8:40write descriptors, having inherited the
- 8:43descriptors from the execution of the
- 8:45pipe system call, are readers and
- 8:48writers. Unless otherwise specified,
- 8:50the close function can be used to close
- 8:53the descriptor that it is not going to
- 8:56use, thus converting a process into a
- 8:58writer-only or reader-only process. The
- 9:03diagram shows a single process that
- 9:05creates a pipe and by default it is a
- 9:08writer and a reader. That process
- 9:13writes to the pipe constantly. Of
- 9:18course, since the pipe has a finite
- 9:20storage capacity, at some point the
- 9:23pipe will fill up. What will happen
- 9:27then when the process tries to write to
- 9:31a full pipe, knowing that the process
- 9:34is also a reader because it did not
- 9:38close the file descriptor? The
- 9:42following code shows a reader and
- 9:45writer process in Pythes. You will see
- 9:49that there is no system call here that
- 9:51creates any child processes, but there
- 9:53is a system call that creates the pipe.
- 9:56So this process that creates the pipe
- 9:58becomes both a reader and a writer of
- 10:01the pipe. Furthermore, we do not see
- 10:04any call to close. Note that the
- 10:07process enters an infinite writing
- 10:10cycle in the PEP. So, if it writes
- 10:14constantly, it is assumed that at some
- 10:16point, if there is no reader emptying
- 10:21the pipe at the reading end, the pipe
- 10:24will fill up. When the pipe fills up,
- 10:29then the process will try to write to
- 10:32the pipe again. At that point, the
- 10:37process will be blocked in the WR
- 10:39system call to write to file descriptor
- 10:431, waiting infinitely until a reader
- 10:46process reads and makes space in the
- 10:49pipe. In this case, since no reading is
- 10:54seen on the pipe, the process will be
- 10:57blocked indefinitely. Well, this
- 11:00process is a reader and writer because
- 11:03it did not close P0 indicating that it
- 11:06would not read from the pipe. So, here
- 11:09the process writes until the pipe is
- 11:11full. When the pipe is full, since the
- 11:16pipe has a limited byte capacity to
- 11:18store, the process blocks on the right
- 11:21waiting for the pipe to be read so that
- 11:24free space is generated for writing,
- 11:27since reading is destructive. It should
- 11:31be noted that the writer process blocks
- 11:33on writing when the pipe is full and if
- 11:36there is a reader process. This is very
- 11:39important. It blocks on writing if
- 11:41there is a reader process. If the pipe
- 11:45is full and the process wants to write
- 11:48to the pipe, but there is no reader, it
- 11:51is a completely different situation.
- 11:54What happens to the reader when it
- 11:56tries to read from an empty pipe? A
- 12:00reader process reads from a pipe and
- 12:02blocks when the pipe is empty. The
- 12:05diagram shows a parent process that is
- 12:08now constantly reading from a pipe. It
- 12:13is the same situation as the previous
- 12:15case or similar. Why? Because the
- 12:18parent process is both a reader and a
- 12:20writer. It has to be both a reader and
- 12:23a writer for this situation to occur.
- 12:26In this case, the only process is a
- 12:28writer and a reader. By default, when a
- 12:30pipe is created, the process or
- 12:32processes that obtain the read and
- 12:34write descriptors are readers and
- 12:36writers. If not, if otherwise specified
- 12:38, the close function can be used to
- 12:40close the descriptor that is not going
- 12:42to be used, thus converting a process
- 12:44into a reader-only or writer-only
- 12:46process. We are reiterating this, but
- 12:50this will help you understand the
- 12:52handling or programming of PPES. Here
- 12:58we have some code that shows a process
- 13:00that creates a pipe, has no children,
- 13:03is a single process and that is
- 13:05constantly reading from a pipe. Of
- 13:09course, this process will block on the
- 13:12first attempt to read. Why? Because the
- 13:16pipe is empty. It is very important
- 13:20that in order for a reader process to
- 13:23block in a read when the pipe is empty,
- 13:26there must be at least one writer
- 13:29process. If we have a reader process
- 13:33that tries to read from an empty P and
- 13:36there are no writers, the situation is
- 13:38different. This process is a reader and
- 13:44writer because it did not close P1
- 13:46indicating that it would not write to
- 13:48the pipe. So here the process reads
- 13:51until the pipe is empty. When the pipe
- 13:54is empty, in fact the pipe is empty,
- 13:56since no process writes to it. As we
- 13:59mentioned before, the process will
- 14:02block in the first RIP attempt it makes
- 14:05on P sub0. The process blocks in the
- 14:08RIT waiting for a write to be made to
- 14:10the P so that the reading can be
- 14:12unblocked. Of course, since there is no
- 14:15writing, no process or the process
- 14:19itself is not writing, this process
- 14:22remains blocked indefinitely in the RIP
- 14:26. It is important to note that the
- 14:29reader process blocks in reading when
- 14:31the pipe is empty and if there is a
- 14:33writer process. Why? If there is no
- 14:37writer process, then the situation is
- 14:39completely different. In the two
- 14:42previous cases we had parent processes
- 14:45without children. Well, perhaps we
- 14:48could have avoided using the word
- 14:50parent and simply used process, but
- 14:53anyway, in the two previous cases we
- 14:55had parents and only processes. In this
- 14:59case we already have two processes. We
- 15:02have a parent process and a child
- 15:04process. What happens to the writer
- 15:07process when all the reader processes
- 15:10finish? This means that we will have a
- 15:13writer or a writer process on a pipe,
- 15:16but there will be no reader processes.
- 15:22Let's suppose that a child process
- 15:24writes the alphabet in the pipe and the
- 15:26parent process reads the alphabet from
- 15:28the same pipe. But when the reader
- 15:32reads the letter r, it closes the
- 15:34reading channel or, in other words, it
- 15:37closes P0. So, we no longer have a
- 15:42reader, only the child process is left
- 15:46writing to the PE. So, the child
- 15:50process is immediately terminated by
- 15:53the operating system. For this to
- 15:56happen we have a writer and a reader
- 16:02and only one writer and one reader.
- 16:05That's why the parent closes its
- 16:07channel or closes its write descriptor
- 16:09file. It will only read. There we show
- 16:14that we only have one reader and the
- 16:16child closes its read descriptor file.
- 16:20There we have exactly one child process
- 16:23that is only going to write. In other
- 16:25words, we have a reader and a writer.
- 16:29That is what we need to show this
- 16:31situation. The writer process is
- 16:35terminated in writing when the reader
- 16:38process closes its read descriptor file
- 16:41, executing, of course, the close of p
- 16:44or simply the child process, this,
- 16:47sorry, the parent process, which is the
- 16:50reader, ends. So, we repeat, we have a
- 16:54writer process, only one writer process
- 16:57, we have only one reader process. And
- 17:01what happens when we have a writer
- 17:05without a reader? Well, at the same
- 17:09time that there is no longer a reader
- 17:12process, the writer process ends as
- 17:15long as it is in the WR right. Okay,
- 17:18here we have the code that shows this
- 17:20situation. We see that on line 8 the
- 17:24process creates the pipe, on line 9 the
- 17:27process creates a child. On line 12 the
- 17:30execution of the parent process begins,
- 17:34which on line 13 closes the write
- 17:36descriptor file because it is only
- 17:39going to read. Okay, then we have a
- 17:43loop that the parent process reads on
- 17:49the pipe until it reads the letter R.
- 17:53When it reads the letter R, it exits
- 17:56the loop and closes the reading writer
- 18:00file. This means that the parent is no
- 18:03longer a writer. It stopped being a
- 18:07writer on line 13 and now stops being a
- 18:10reader on line 21. This does not mean
- 18:13that the child, whose code starts on
- 18:16line 25, is now a writer. It has
- 18:20written the alphabet up to the letter
- 18:22R. On the letter R it says, "I'm not
- 18:26reading anymore." So, when the child
- 18:31process wants to write on line 29 with
- 18:34the WR on the descriptor file, it will
- 18:37find or at that moment there is no
- 18:40reader, so the child process is
- 18:43automatically terminated. What happens
- 18:48to the reader process when all the
- 18:50writer processes finish? We maintain
- 18:54the same scenario as in the previous
- 18:56case, but now considering that the
- 18:59writer process, when it writes the
- 19:02letter R to the pipe, closes its
- 19:04writing channel with the close of P
- 19:07sub1. Then the child process reads from
- 19:13the pipe until it is empty and is not
- 19:15blocked, it continues its execution.
- 19:19The diagram shows the same diagram as
- 19:22the previous case: a parent that only
- 19:25reads, a child that only writes; and we
- 19:28consider, and it is important, that the
- 19:31reader process does not block in
- 19:33reading when the pipe is empty and
- 19:36there are no writers, because it or the
- 19:39writers closed their file descriptor by
- 19:42executing clock (P1) or simply
- 19:45terminated. So, let's summarize. A
- 19:50reader process does not block in
- 19:53reading when there are no writers. It
- 19:58continues its execution. Here we have
- 20:01the code, the C language of this
- 20:04situation. Eh, we see that when the
- 20:08child writes the letter R in the pipe,
- 20:11eh, it exits the writing cycle and
- 20:14closes its writing descriptor file.
- 20:19Since it closed its reading writer file
- 20:22on line 26, it means that there is no
- 20:24longer a writing process in the
- 20:26communication. So, look at line 13 to
- 20:33line 22, how the parent process reads
- 20:40until the pipe is empty, but when the
- 20:43pipe is empty, we put an infinite loop
- 20:47there to show that it continues
- 20:50executing. Well, the most important
- 20:53characteristics of pipes. Pipes only
- 20:57allow parent processes to communicate.
- 20:59We can say that parent processes are
- 21:01those that are created using a fork and
- 21:04that have a parent-child relationship.
- 21:07Communication between processes using
- 21:10pipes is unidirectional. This means
- 21:14that only one end of the pipe is
- 21:16written to and the other end of the
- 21:18pipe is read to, represented in the
- 21:20code by the ray p sub1 and the read p
- 21:22sub0. The writer process blocks on
- 21:26writing when the pipe is full and if
- 21:29there is at least one reader process,
- 21:31the reader process blocks on reading
- 21:34when the pipe is empty and if there is
- 21:37at least one writer process. Reading
- 21:40from a pipe is destructive. The reading
- 21:43order is fifo. The writer process is
- 21:47terminated on writing by the system.
- 21:50When the reader process closes its
- 21:52reading channel with cloper or
- 21:54terminates, which is the same as saying
- 21:57when there are no more reader processes
- 21:59, the writer process is terminated in
- 22:01the attempt to write to the pipe. A
- 22:05reader process, a reader process if it
- 22:10is blocked in the read in an empty pipe
- 22:12waiting for a writer process to write,
- 22:15but the writer closes its writing
- 22:17channel with the clock P1 or for some
- 22:20reason terminates, the reader process
- 22:22is unblocked and continues with the
- 22:25logical execution of its code if it was
- 22:27programmed that way. Well, we have
- 22:31finished the first part of the
- 22:32introduction to Pipes programming.
About this transcript
This page contains the full transcript of pipes 1 by juancarlosjromer, generated from the public captions YouTube serves with the video. The transcript has 3,045 words across 443 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.