Week - 5
Week - 5
a) Aim:
Write C programs to illustrate the following IPC mechanisms: a) Pipes
Description:
Ordinary pipes allow two processes to communicate in standard producer– consumer fashion:
the producer writes to one end of the pipe (the write-end) and the consumer reads from the
other end (the read-end).
On UNIX systems, A pipe is created by calling the pipe function
General Form: int pipe(int fd[2]);
Two file descriptors are returned through the fd argument: fd[0] is open for reading, and
fd[1] is open for writing. The output of fd[1] is the input for fd[0].
Algorithm
1. Create the pipe and create the process.
2. Get the input in the main process and pass the output to the child process using pipe.
3. Perform the operation given in the child process and print the output.
4. Stop the program.
Program:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int ret_val;
int fd[2];
char buff[100]="";
char string1[100]="";
printf("\nEnter the msg= ");
scanf("%s",&string1);
ret_val = pipe(fd);
if (ret_val != 0)
{
printf("Unable to create a pipe");
exit(1);
}
if (fork() == 0)
{
close(fd[0]);
ret_val = write(fd[1],string1,strlen(string1));
if (ret_val != strlen(string1))
{
printf("Write did not return expected value\n");
exit(2);
}
}
else
{
close(fd[1]);
ret_val = read(fd[0],buff,strlen(string1));
if (ret_val != strlen(string1))
{
printf("Read did not return expected value\n");
exit(3);
}
printf("Parent read");
printf(" %s",buff);
printf(" from the child program\n");
}
exit(0);
}
b) Aim:
Write C programs to illustrate the following IPC mechanisms: b) FIFOs
Description:
Named pipes are referred to as FIFOs in UNIX systems.
Creating a FIFO is similar to creating a file.
General Form: int mkfifo(const char *path, mode_t mode);
Once we have used mkfifo to create a FIFO, we open it using open. Normal file I/O
functions(close, read,write,unlink etc) all work with FIFOs.
pipe_creation.c
Algorithm:
1. Start
2. Create a FIFO using mkfifo command
3. Check the value of file descriptor to check whether FIFO is successfully created or not.
4. Stop
Program:
#include<stdio.h>
int main()
{
int f1,f2;
f1 = mkfifo("pipeA",0666);
if(f1<0)
printf("\npipeA was not created");
else
printf("\npipeA created");
f2 = mkfifo("pipeB",0666);
if(f2<0)
printf("\npipeB was not created");
else
printf("\npipeB is created\n");
return 0;
}
leftTerminal.c
Algorithm:
1. Start
2. Open the pipe for writing
3. Check for opening error
4. If no error write data to the FIFO
5. Open the pipe for reading
6. Check for opening error
7. If no error read from the FIFO
8. Stop
Program:
#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char str[256]="start";
int fifo_write,fifo_read;
while(strcmp(str,"end")!=0)
{
fifo_write= open("pipeA",O_WRONLY);
if(fifo_write<0)
printf("\nError opening pipe");
else
{
printf("\nEnter text:\n");
scanf("%s",str);
write(fifo_write,str,255*sizeof(char));
close(fifo_write);
}
fifo_read=open("pipeB",O_RDONLY);
if(fifo_read<0)
printf("\nError opening write pipe");
else
{
read(fifo_read,str,255*sizeof(char));
close(fifo_read);
printf("\n%s",str);
}
}
return 0;
}
rightTerminal.c
Algorithm:
1. Start
2. Open the pipe for reading
3. Check for opening error
4. If no error read from the FIFO
5. Open the pipe for writing
6. Check for opening error
7. If no error write data to the FIFO
8. Stop
Program:
#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char str[256]="start";
int fifo_read,fifo_write;
while(strcmp(str,"end")!=0)
{
fifo_read=open("pipeA",O_RDONLY);
if(fifo_read<0)
printf("\nError opening read pipe");
else
{
read(fifo_read,str,255*sizeof(char));
close(fifo_read);
printf("\n%s",str);
}
fifo_write=open("pipeB",O_WRONLY);
if(fifo_write<0)
printf("\nError opening write pipe");
else
{
printf("\nEnter text:\n");
scanf("%s",str);
write(fifo_write,str,255*sizeof(char));
close(fifo_write);
}
}
return 0;
}
How to Run:
Run pipe_creation.c first. Then close it. Then run leftTerm.c. Without closing it, open a new
terminal window and run rightTerm.c. Start typing from leftTerm.c and then in rightTerm.c.
c) Aim:
Write C programs to illustrate the following IPC mechanisms: c) Message Queues
Description:
A message queue is a linked list of messages stored within the kernel and identified by a
message queue identifier.
ftok(): is use to generate a unique key.
msgget
The first function normally called is msgget to either open an existing queue or create a
new queue.
General Form: int msgget(key_t key, int flag);
msgsnd
Data is placed onto a message queue by calling msgsnd.
General Form: int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
msgrcv
Messages are retrieved from a queue by msgrcv.
General Form: ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
msgctl
The msgctl function performs various operations on a queue.
General Form: int msgctl(int msqid, int cmd, struct msqid_ds *buf );
Algorithm:
1. Create two processes, one is for sending into message queue (msgq_send.c) and another is
for retrieving from the message queue (msgq_recv.c)
2. Creating the key, using ftok() function. For this, initially file msgq.txt is created to get a
unique key.
3. The sending process performs the following.
Reads the string input from the user
Removes the new line, if it exists
Sends into message queue
Repeats the process until the end of input (CTRL + D)
Once the end of input is received, sends the message “end” to signify the end of the
process
4. In the receiving process, performs the following.
Reads the message from the queue
Displays the output
If the received message is “end”, finishes the process and exits
Program:
Writer process
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main()
{
key_t key;
int msgid;
message.msg_type = 1;
int i=0;
while(i<2){
printf("Enter the message : ");
fgets(message.msg_text, 100, stdin);
// msgget creates a message queue
// and returns identifier
msgid = msgget(key, 0666 | IPC_CREAT);
Reader process
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main()
{
key_t key;
int msgid;
return 0;
}
d) Aim:
Write C programs to illustrate the following IPC mechanisms: d) Shared Memory
Description:
Shared memory allows two or more processes to share a given region of memory.
This is the fastest form of IPC, because the data does not need to be copied between the
client and the server.
ftok(): is use to generate a unique key.
shmget
The first function called is usually shmget, to obtain a shared memory identifier
General Form: int shmget(key_t key, size_t size, int flag);
shmctl
The shmctl function is the catchall for various shared memory operations.
General Form: int shmctl(int shmid, int cmd, struct shmid_ds *buf );
shmat
Once a shared memory segment has been created, a process attaches it to its address
space by calling shmat.
General Form: void *shmat(int shmid, const void *addr, int flag);
shmdt
When we’re done with a shared memory segment, we call shmdt to detach it. This does
not remove the identifier and its associated data structure from the system. The identifier
remains in existence until some process (often a server) specifically removes it by calling
shmctl with a command of IPC_RMID.
General Form: int shmdt(const void *addr);
Writing.c
Algorithm
1. Start
2. Use ftok to generate unique key
3. shmget returns an identifier in shmid
4. Use shmat to attach to shared memory
5. Write data to the shared memory
6. detach from shared memory
7. Stop
Program:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
// ftok to generate unique key
key_t key = ftok("shmfile",65);
return 0;
}
Reading.c
Algorithm
1. Start
2. Use ftok to generate unique key
3. shmget returns an identifier in shmid
4. Use shmat to attach to shared memory
5. Read data from the shared memory
6. detach from shared memory
7. Remove the shared memory completely.
8. Stop
Program:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
int main()
{
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
return 0;
}