Pipes are basically used for communicating information between two processes.
There are two types of pipes:
- ordinary pipe
- Named pipe
Ordinary Pipe:
- simple pipes are unidirectional in nature (one-way comm)
- two-way communication can be achieved by creating 2 pipes
- pipe cannot be accessed from the outside the process that creates it
- Hence it is used mostly for parent and child process communication
creation and use:
- pipe() function is used to create a pipe. This actually creates special file
- read(), write(), close() system calls can be used to access this file
- int file_descriptor[2] array is used as file_descriptor to access file.
- file_descriptor[0] = read from file
- file_descriptor[1] = write to file
- one of the file descriptor(read/write) should be closed in the respective process to make it unidirectional. This is done to avoid Deadlock condition and exploit parallelism
Named Pipes:
- named pipes are like FIFOs
- created using mkfifo() system calls and opereated using open, read, write and close(0 system calls
- they appear as files in file system once created
- they remain as it is until they are deleted explicitly
- multiple process on same machine can use named pipe
- For communication over network, socket wrapper need to be used
Named pipe Example:
$mkfifo demo_fifo
$exec 3<> demo_fifo
$ls -l >&3$cat demo_fifo
mkfifo - create named pipe
exec - to a assigned 3 as file descriptor for named pipe
$ls -l >&3 add output of ls -l to named pipe
cat - read the data from named pipe
Following is example of Ordinary pipe:
---------------------------------------------------------------------------------
linux_pipe.c
---------------------------------------------------------------------------------
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 50
#define READ_END 0
#define WRITE_END 1
int main(int argc, char *argv[]){
char write_msg[BUFFER_SIZE] = "message over pipe";
char read_msg[BUFFER_SIZE];
int file_descriptor[2];
pid_t pid;
// create pipe
if (pipe(file_descriptor) == -1){
fprintf(stderr, "ERROR: Pipe creation failed");
return 1;
}
pid = fork(); // fork process
if (pid < 0){ // process forking failure
fprintf(stderr, "ERROR: Process forking failure");
}
else if (pid == 0){ //this is child process
printf("Inside child process\n");
close(file_descriptor[WRITE_END]); //close the write end of the pipe
read(file_descriptor[READ_END], read_msg, BUFFER_SIZE); //read message from pipe. wait until message is received
printf("Read data = %s", read_msg);
close(file_descriptor[READ_END]); //close read end of the pipe
}
else { //this is parent process
sleep(5); //Too verify child waits at read() for 5sec until it receives message
close(file_descriptor[READ_END]); //close read end of the pipe
write(file_descriptor[WRITE_END], write_msg, strlen(write_msg) + 1); //writing message to pipe
printf("Task of writing message to pipe completed\n");
close(file_descriptor[WRITE_END]); //close write end of the pipe
}
return 0;
}
---------------------------------------------------------------------------------
output
---------------------------------------------------------------------------------
output
---------------------------------------------------------------------------------
Inside child process
Task of writing message to pipe completed
Read data = message over pipe
No comments:
Post a Comment