Applying C - Pipes |
Written by Harry Fairhead | ||||||
Monday, 03 January 2022 | ||||||
Page 2 of 2
Anonymous PipesAs well as named pipes there are anonymous pipes, usually just referred to as a pipe, which only have file descriptors but otherwise work in the same way as named pipes. To create an anonymous pipe all you have to do is call the pipe function with a two-element array to receive two file descriptors: int fd[2]; pipe(fd); When pipe returns it has stored a read file descriptor in fd[0] and a write descriptor in fd[1]. These can be used immediately to read and write to the pipe - you don't need to open any files. The only question is how does the reading and writing process get the file descriptors? The answer is that they have to be related - one has to be a child process of the other and hence it inherits open file descriptors. The usual way to implement pipes between processes is to first create the pipe and then use fork to create a child process. For more information on fork see Chapter 12. There are other ways of passing a file descriptor to another process. You could use shared memory or a shared file. Anonymous pipes also work with threads and in this case there is no need to worry about passing file descriptors as threads share file descriptors. However in most cases it is simpler to allow threads to share global data structures than to make use of an anonymous pipe for interthread communication. An Anonymous Pipe ExampleA simple implementation of the reader/writer example using pipes is: #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(int argc, char** argv) { int value1 = 0x55555555; int value2; int fd[2]; pipe(fd); if (fork() == 0) { close(fd[0]); for (;;) { value1 = ~value1; write(fd[1], &value1, 4); printf("W%X", value1); fflush(stdout); sleep(1); } } else { close(fd[1]); for (;;) { read(fd[0], &value2, 4); if ((value2 != 0x55555555) && In this case we simply call pipe to get a read and a write descriptor. The fork creates a new process which is a complete copy of the program. The child code "knows" which one it is as fork returns 0 for it and not for the parent process. In this way the child process executes the if clause, i.e. the writer, and the parent executes the else clause, i.e. the reader. This code omits all error checking and you need to take into account the need to deal with the possibility that the pipe or the fork might fail and that the reader or writer might close the pipe so stalling the other process. Notice that both named and anonymous pipes can be used with processes or threads. In the case of anonymous pipes you would work in exactly the same way as for the fork example, but in this case sharing the same copy of the file descriptor array. It is also worth mentioning that pipes are used to connect command line operations using the pipe symbol |. In this case stdout is connected using a pipe to stdin. The easiest way to use this mechanism in a program is to use the popen and pclose command. However, this isn't much used in low-level or systems programming. In chapter but not in this extract:
Summary
Now available as a paperback or ebook from Amazon.Applying C For The IoT With Linux
Also see the companion book: Fundamental C <ASIN:1871962609> <ASIN:1871962617> Related ArticlesRemote C/C++ Development With NetBeans Getting Started With C/C++ On The Micro:bit To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info
|
||||||
Last Updated ( Monday, 03 January 2022 ) |