Linux Read Message Queue as Nonblocking Fd
Prerequisite: 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 information technology(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 ii process is dissimilar.
The default beliefs in a piping is for the writing and reading ends of a pipage is to exhibit blocking behavior, if the partner process is slower. This is bad because the data acquisition procedure can wait on the plotting process(write data). So, during the data acquisition process, cake read telephone call in pipe and program hangs. If we desire this non to happen, we must close the write finish in process before read cease call.
In simple language,
- A read telephone call gets as much data as it requests or equally much data as the pipe has, whichever is less
- If the pipe is empty
- Reads on the pipe volition return EOF (return value 0) if no procedure has the write end open up
- If some process has the pipe open for writing, read will block in apprehension of new data
Non-blocking I/O with pipes
Sometimes information technology's convenient to accept I/O that doesn't block i.e we don't want a read call to block on i in case of input from the other. Solution for this is the given part:
To specify not-blocking choice: #include<fcntl.h> int fd; fcntl(fd, F_SETFL, O_NONBLOCK);
- fd: file descriptor
- F_SETFL: Set the file condition flags to the value specified by arg. File access manner here in our purpose utilise only for O_NONBLOCK flag.
- O_NONBLOCK: use for not-blocking selection.
- 0: return on successful
- -i: return on error, set errorno
Subsequently this function runs successfully, a phone call to read/write returns -1 if pipe
is empty/full and sets errno to EAGAIN
Case: Kid writes "hello" to parent every iii seconds and Parent does a non-blocking read each second.
C
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> // library for fcntl function
#define MSGSIZE 6
char
* msg1 ="hullo";
char
* msg2 ="bye !!";
int
main()
{
int
p[2], i;
if
(pipe(p) < 0)
exit
(1);
if
(fcntl(p[0], F_SETFL, O_NONBLOCK) < 0)
exit
(2);
switch
(fork()) {
case
-1:
get out
(3);
case
0:
child_write(p);
break
;
default
:
parent_read(p);
break
;
}
render
0;
}
void
parent_read(
int
p[])
{
int
nread;
char
buf[MSGSIZE];
close(p[one]);
while
(1) {
nread = read(p[0], buf, MSGSIZE);
switch
(nread) {
case
-1:
if
(
errno
== EAGAIN) {
printf
("(pipe empty)\n");
sleep(one);
break
;
}
else
{
perror
("read");
exit
(iv);
}
case
0:
printf
("Stop of chat\n");
close(p[0]);
exit
(0);
default
:
printf
("MSG = % s\north", buf);
}
}
}
void
child_write(
int
p[])
{
int
i;
close(p[0]);
for
(i = 0; i < three; i++) {
write(p[ane], msg1, MSGSIZE);
sleep(iii);
}
write(p[1], msg2, MSGSIZE);
go out
(0);
}
Output:
(pipe empty) MSG=hello (pipe empty) (pipe empty) (pipe empty) MSG=hullo (pipe empty) (pipe empty) (pipe empty) MSG=hi (pipe empty) (pipe empty) (pipage empty) MSG=bye!! Stop of conversation
Atomic writes in pipe
Atomic ways 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 exist an instantaneous unit means nothing else in the organization 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 information), simply once it does brainstorm it finishes immediately.
Information Writes of upward to PIPE_BUF (4096 Bytes) are atomic. Reading or writing a larger amount of data may not be atomic; For case, output data from other processes sharing the descriptor may exist interspersed. Also, in one case PIPE_BUF characters accept been written, further writes volition block until some characters are read
Example: Process one sends a 100-byte message at the same fourth dimension, process two sends a 100-byte message No guarantee about the lodge, just piping volition receive all of 1 message followed by all of the other.
In non atomic writes for larger writes there is no such guarantee, data could get confusingly intermingled like, this:
Pipe Capacity
- A pipe can concord a limited number of bytes.
- Writes fill up the pipe and block when the pipage is full
- They block until another process reads plenty data at the other end of the pipe and render when all the information given to write take been transmitted
- Chapters of a piping is at least 512 bytes, usually more (arrangement dependent)
C
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int
count = 0;
void
alrm_action(
int
signo)
{
printf
(
"Write blocked after %d characters\n"
, count);
get out
(0);
}
int
main()
{
int
p[2];
char
c =
'x'
;
signal
(SIGALRM, alrm_action);
if
(pipage(p) == -1)
leave
(one);
while
(1) {
alarm(five);
write(p[one], &c, 1);
++count;
warning(0);
}
}
Output:
Write blocked after 65536 characters //output depend on the arrangement so output may change in different system
Here, in while loop kickoff 5 2nd alarm is set after write() call writes one character 'x' in the pipe. And count variable is used for count graphic symbol write in the pipe. potent>alarm(0) means cancel the set alarm of 5 second. After some fourth dimension when pipe capacity is full and so write() phone call is block and program does not execute adjacent instruction, afterward 5 second fix alert ringing and send indicate SIGALRM . After that alram_action handler executes and prints how many maximum character can be written past pipage.
This commodity is contributed past Kadam Patel. If you like GeeksforGeeks and would like to contribute, yous tin also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. Come across your article appearing on the GeeksforGeeks principal page and help other Geeks.
Please write comments if you discover anything incorrect, or yous want to share more information near the topic discussed above.
Source: https://www.geeksforgeeks.org/non-blocking-io-with-pipes-in-c/
Postar um comentário for "Linux Read Message Queue as Nonblocking Fd"