Exercises:Pipes: Difference between revisions

From COMP15212 Wiki
gravatar Yuron [userbureaucratinterface-adminsysopPHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+YnVyZWF1Y3JhdDxiciAvPmludGVyZmFjZS1hZG1pbjxiciAvPnN5c29wPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs)
m (1 revision imported)
pc>Yuron
No edit summary
Line 10: Line 10:


----
----
Before trying this demonstration you should be happy with the basic
Before trying this demonstration you should be happy with the basic <code>fork()</code> function.  This program splits into two processes having set up a pipe for them to communicate with.  One process then sends some information (a string, in this case) and the other reads it and prints it out.
<code>fork()</code> function.  This program splits into two processes having
set up a pipe for them to communicate with.  One process then sends
some information (a string, in this case) and the other reads it and
prints it out.


Compile and run <code>pipe.c</code>.
Compile and run <code>pipe.c</code>.


Before the <code>fork()</code> call the call to <code>pipe()</code> creates the
Before the <code>fork()</code> call the call to <code>pipe()</code> creates the communications pipe.  A descriptor is returned (in a small array <code>pipefd</code>) with values identifying the output and input ends of this pipe.
communications pipe.  A descriptor is returned (in a small array
<code>pipefd</code>) with values identifying the output and input ends of this
pipe.


After the fork the processes follow different branches of the
After the fork the processes follow different branches of the <code>if ... else ...</code>.
<code>if ... else ...</code>.


The first branch pauses for a second – just for demonstration
The first branch pauses for a second – just for demonstration purposes – then sends a string (‘message’) using the
purposes – then sends a string (‘message’) using the
<code>write()</code> call to the new pipe input end (‘1’).
<code>write()</code> call to the new pipe input end (‘1’).


The second branch immediately tries to <code>read()</code> from the output
The second branch immediately tries to <code>read()</code> from the output (‘0’) end of the pipe; it will wait until there is
(‘0’) end of the pipe; it will wait until there is
something there.  The input is directed to a ‘buffer’ and has been limited to 20 bytes in this case to avoid a buffer overflow. If the input arrives successfully this process prints it out.
something there.  The input is directed to a ‘buffer’ and
has been limited to 20 bytes in this case to avoid a buffer overflow.
If the input arrives successfully this process prints it out.
<blockquote>
<blockquote>
Caveat: if you try a longer string, remember that the
Caveat: if you try a longer string, remember that the “%s” in <code>printf()</code> will expect a string terminator.
“%s” in <code>printf()</code> will expect a string terminator.
</blockquote>
</blockquote>
----
----
Line 44: Line 31:


=== Part 1 ===
=== Part 1 ===
If you’ve followed that you should be able to send a reply from the
If you’ve followed that you should be able to send a reply from the child process to the parent.  Unix pipes are unidirectional so you’ll need to create another on to pass data in the other direction.
child process to the parent.  Unix pipes are unidirectional so you’ll
need to create another on to pass data in the other direction.


Try it.
Try it.


Note that the data in the pipe is an <strong>unstructured</strong> <em>stream</em> of
Note that the data in the pipe is an <strong>unstructured</strong> <em>stream</em> of bytes.  Experiment with sending a second (short! – or increase the receiver buffer size) string: if you do this before the <code>read()</code> is rescheduled then the data will be concatenated.  (This may be hard to see in a print-out because, of course, the first string terminator is still present; check the <em>number</em> of bytes moved.)  If the <code>read()</code> runs before a second <code>write()</code> then another <code>read()</code> call will be needed to read everything out.
bytes.  Experiment with sending a second (short! – or increase the
receiver buffer size) string: if you do this before the <code>read()</code> is
rescheduled then the data will be concatenated.  (This may be hard to
see in a print-out because, of course, the first string terminator is
still present; check the <em>number</em> of bytes moved.)  If the <code>read()</code>
runs before a second <code>write()</code> then another <code>read()</code> call will be
needed to read everything out.


When using such a communications mechanism there may be the need for
When using such a communications mechanism there may be the need for the <em>application</em> to impose some control protocol to structure and give meaning to the bytes.  Play!
the <em>application</em> to impose some control protocol to structure and
give meaning to the bytes.  Play!


=== Part 2 ===
=== Part 2 ===
Go back to the main [[Pipes | pipes]] page and work through the section
Go back to the main [[pipes]] page and work through the section labelled “Named pipes” within a shell window.
labelled “Named pipes” within a shell window.
----
 
=== Submission ===
Submit your modified pipe-communicating program (from part 1) as
[<code>ex7.c</code>].  It should include enough <em>comments</em> for it to be clear
what you have done.
(Commenting is a habit you should be getting into anyway!)
----
----


{{PageGraph}}
{{PageGraph}}
{{Category|Exercises}}
{{Category|Exercises}}

Revision as of 10:11, 8 August 2019

On path: Exercises 0: Exercises • 1: Pointer Exercise • 2: Arguments Exercise • 3: Malloc Exercise • 4: Structs Exercise • 5: Processes Exercise • 6: Shared memory Exercise • 7: Pipes Exercise • 8: Exceptions Exercise • 9: Synchronisation Exercise • 10: Files Exercise • 11: Threads Exercise • 12: Unix proc Exercise
Depends on Pipes

Download exercise files

The purpose of this exercise is:

  • to demonstrate inter-process communication through a ‘pipe

Before trying this demonstration you should be happy with the basic fork() function. This program splits into two processes having set up a pipe for them to communicate with. One process then sends some information (a string, in this case) and the other reads it and prints it out.

Compile and run pipe.c.

Before the fork() call the call to pipe() creates the communications pipe. A descriptor is returned (in a small array pipefd) with values identifying the output and input ends of this pipe.

After the fork the processes follow different branches of the if ... else ....

The first branch pauses for a second – just for demonstration purposes – then sends a string (‘message’) using the write() call to the new pipe input end (‘1’).

The second branch immediately tries to read() from the output (‘0’) end of the pipe; it will wait until there is something there. The input is directed to a ‘buffer’ and has been limited to 20 bytes in this case to avoid a buffer overflow. If the input arrives successfully this process prints it out.

Caveat: if you try a longer string, remember that the “%s” in printf() will expect a string terminator.


Exercise

Part 1

If you’ve followed that you should be able to send a reply from the child process to the parent. Unix pipes are unidirectional so you’ll need to create another on to pass data in the other direction.

Try it.

Note that the data in the pipe is an unstructured stream of bytes. Experiment with sending a second (short! – or increase the receiver buffer size) string: if you do this before the read() is rescheduled then the data will be concatenated. (This may be hard to see in a print-out because, of course, the first string terminator is still present; check the number of bytes moved.) If the read() runs before a second write() then another read() call will be needed to read everything out.

When using such a communications mechanism there may be the need for the application to impose some control protocol to structure and give meaning to the bytes. Play!

Part 2

Go back to the main pipes page and work through the section labelled “Named pipes” within a shell window.