Requisito previo: manejo de señales C , IPC a través de memoria compartida
Una señal se usa en el sistema UNIX para notificar a un proceso que ha ocurrido un evento en particular. Una señal puede recibirse de forma síncrona o asíncrona, según la fuente y el motivo por el que se señaliza el evento. Una señal debe seguir el siguiente patrón:
1. Una señal es generada por la ocurrencia de un evento particular.
2. Una señal generada se entrega a un proceso particular.
3. La señal debe ser manejada después de recibirla en el proceso.
En este problema, el mensaje se envía de un usuario a otro utilizando la función de eliminación . La función de matar toma dos entradas: identificación del proceso del receptor y tipo de señal. Para este propósito, usamos una memoria compartida donde almacenamos las identificaciones de proceso de dos procesos. Usamos una función de controlador que imprimirá el mensaje recibido de otro proceso. El Usuario2 comenzará a enviar un mensaje al Usuario1 y luego continuarán chateando.
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; // handler function to print message received from user2 void handler(int signum) { // if signum is SIGUSR1, then user 1 is receiving a message from user2 if (signum == SIGUSR1) { printf("Received User2: "); puts(shmptr->buff); } } int main() { // process id of user1 int pid = getpid(); int shmid; // key value of shared memory int key = 12345; // shared memory create shmid = shmget(key, sizeof(struct memory), IPC_CREAT | 0666); // attaching the shared memory shmptr = (struct memory*)shmat(shmid, NULL, 0); // store the process id of user1 in shared memory shmptr->pid1 = pid; shmptr->status = NotReady; // calling the signal function using signal type SIGUSER1 signal(SIGUSR1, handler); while (1) { while (shmptr->status != Ready) continue; sleep(1); // taking input from user1 printf("User1: "); fgets(shmptr->buff, 100, stdin); shmptr->status = FILLED; // sending the message to user2 using kill function 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; // handler function to print message received from user1 void handler(int signum) { // if signum is SIGUSR2, then user 2 is receiving a message from user1 if (signum == SIGUSR2) { printf("Received From User1: "); puts(shmptr->buff); } } // main function int main() { // process id of user2 int pid = getpid(); int shmid; // key value of shared memory int key = 12345; // shared memory create shmid = shmget(key, sizeof(struct memory), IPC_CREAT | 0666); // attaching the shared memory shmptr = (struct memory*)shmat(shmid, NULL, 0); // store the process id of user2 in shared memory shmptr->pid2 = pid; shmptr->status = NotReady; // calling the signal function using signal type SIGUSR2 signal(SIGUSR2, handler); while (1) { sleep(1); // taking input from user2 printf("User2: "); fgets(shmptr->buff, 100, stdin); shmptr->status = Ready; // sending the message to user1 using kill function kill(shmptr->pid1, SIGUSR1); while (shmptr->status == Ready) continue; } shmdt((void*)shmptr); return 0; }
Producción: