Prequisite: pipe() System call
When I/O block in pipe() happens?
Consider two processes, one process that’s gathering data(read data) in real time and another process that’s plotting it(write data). The two processes are connected by a pipe, with the data acquisition process feeding the data plotting process. Speed of the data acquisition of two process is different.
The default behavior in a pipe is for the writing and reading ends of a pipe is to exhibit blocking behavior, if the partner process is slower. This is bad because the data acquisition process can wait on the plotting process(write data). So, during the data acquisition process, block read call in pipe and program hangs. If we want this not to happen, we must close the write end in process before read end call.
In simple language,
- A read call gets as much data as it requests or as much data as the pipe has, whichever is less
- If the pipe is empty
- Reads on the pipe will return EOF (return value 0) if no process has the write end open
- If some process has the pipe open for writing, read will block in anticipation of new data
Non-blocking I/O with pipes
Sometimes it’s convenient to have I/O that doesn’t block i.e we don’t want a read call to block on one in case of input from the other. Solution for this is the given function:
To specify non-blocking option: #include<fcntl.h> int fd; fcntl(fd, F_SETFL, O_NONBLOCK);
- fd: file descriptor
- F_SETFL: Set the file status flags to the value specified by arg. File access mode here in our purpose use only for O_NONBLOCK flag.
- O_NONBLOCK: use for non-blocking option.
- 0: return on successful
- -1: return on error, set errorno
After this function runs successfully, a call to read/write returns -1 if pipe
is empty/full and sets errno to EAGAIN
Example: Child writes “hello” to parent every 3 seconds and Parent does a non-blocking read each second.
(pipe empty) MSG=hello (pipe empty) (pipe empty) (pipe empty) MSG=hello (pipe empty) (pipe empty) (pipe empty) MSG=hello (pipe empty) (pipe empty) (pipe empty) MSG=bye!! End of conversation
Atomic writes in pipe
Atomic means no other process ever observes that its partially done. Reading or writing pipe data is atomic if the size of data written is not greater than PIPE_BUF(4096 bytes). This means that the data transfer seems to be an instantaneous unit means nothing else in the system can observe a state in which it is partially complete. Atomic I/O may not begin right away (it may need to wait for buffer space or for data), but once it does begin it finishes immediately.
Data Writes of up to PIPE_BUF (4096 Bytes) are atomic. Reading or writing a larger amount of data may not be atomic; For example, output data from other processes sharing the descriptor may be interspersed. Also, once PIPE_BUF characters have been written, further writes will block until some characters are read
Example: Process 1 sends a 100-byte message at the same time, process 2 sends a 100-byte message No guarantee about the order, but pipe will receive all of one message followed by all of the other.
- A pipe can hold a limited number of bytes.
- Writes fill the pipe and block when the pipe is full
- They block until another process reads enough data at the other end of the pipe and return when all the data given to write have been transmitted
- Capacity of a pipe is at least 512 bytes, usually more (system dependent)
Write blocked after 65536 characters //output depend on the system so output may change in different system
Here, in while loop first 5 second alarm is set after write() call writes one character ‘x’ in the pipe. And count variable is used for count character write in the pipe. strong>alarm(0) means cancel the set alarm of 5 second. After some time when pipe capacity is full then write() call is block and program does not execute next instruction, after 5 second set alarm ringing and send signal SIGALRM. After that alram_action handler executes and prints how many maximum character can be written by pipe.
This article is contributed by Kadam Patel. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to email@example.com. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Conditional or Ternary Operator (?:) in C/C++
- C program to Insert an element in an Array
- Types of Literals in C/C++ with Examples
- asctime() and asctime_s() functions in C with Examples
- time.h header file in C with Examples
- __builtin_inf() functions of GCC compiler
- Count substrings that contain all vowels | SET 2
- How can we use Comma operator in place of curly braces?
- Basic Code Optimizations in C
- Constants vs Variables in C language
- Sum of an array using MPI
- 8086 program to convert a 16 bit decimal number to Hexadecimal
- 8086 program to find GCD of two numbers and print the GCD
- 8086 program to convert a 16 bit Decimal number to Octal