Chat application between two processes using signals and shared memory
Prerequisite: C signal handling, IPC through shared memory
A signal is used in the UNIX system to notify a process that a particular event has occurred. A signal may be received either synchronously or asynchronously depending on the source and the reason for the event being signalled. A signal must follow the following pattern –
1. A signal is generated by the occurrence of a particular event.
2. A generated signal is delivered to a particular process.
3. The signal must be handled after receiving at the process.
In this problem, the message is sent from one user to another user using kill function. kill function takes two inputs – process id of the receiver process and signal type. For this purpose, we use a shared memory where we store the process id(s) of two processes. We use a handler function which will print the message received from another process. User2 will start to send message to User1 and then they will continue chatting.
User 1
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#define FILLED 0
#define Ready 1
#define NotReady -1
struct memory {
char buff[100];
int status, pid1, pid2;
};
struct memory* shmptr;
void handler( int signum)
{
if (signum == SIGUSR1) {
printf ( "Received User2: " );
puts (shmptr->buff);
}
}
int main()
{
int pid = getpid();
int shmid;
int key = 12345;
shmid = shmget(key, sizeof ( struct memory), IPC_CREAT | 0666);
shmptr = ( struct memory*)shmat(shmid, NULL, 0);
shmptr->pid1 = pid;
shmptr->status = NotReady;
signal (SIGUSR1, handler);
while (1) {
while (shmptr->status != Ready)
continue ;
sleep(1);
printf ( "User1: " );
fgets (shmptr->buff, 100, stdin);
shmptr->status = FILLED;
kill(shmptr->pid2, SIGUSR2);
}
shmdt(( void *)shmptr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
|
User 2
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#define FILLED 0
#define Ready 1
#define NotReady -1
struct memory {
char buff[100];
int status, pid1, pid2;
};
struct memory* shmptr;
void handler( int signum)
{
if (signum == SIGUSR2) {
printf ( "Received From User1: " );
puts (shmptr->buff);
}
}
int main()
{
int pid = getpid();
int shmid;
int key = 12345;
shmid = shmget(key, sizeof ( struct memory), IPC_CREAT | 0666);
shmptr = ( struct memory*)shmat(shmid, NULL, 0);
shmptr->pid2 = pid;
shmptr->status = NotReady;
signal (SIGUSR2, handler);
while (1) {
sleep(1);
printf ( "User2: " );
fgets (shmptr->buff, 100, stdin);
shmptr->status = Ready;
kill(shmptr->pid1, SIGUSR1);
while (shmptr->status == Ready)
continue ;
}
shmdt(( void *)shmptr);
return 0;
}
|
Output:
Last Updated :
06 May, 2019
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...