Para que los procesos interactúen se necesitan otras funciones de coordinación más interesantes, así pues vamos a hablar de las señales.
Una señal es como un aviso que un proceso manda a otro proceso, antes las señales las enviaba el Sistema Operativo para indicarnos que el proceso hijo había terminado o que alguien había escrito en el pipe. Los procesos no se comunicaban directamente. Ahora si es posible con la función signal().
#include <signal.h>
void (*signal (int senyal, void (*Func) (int))(int);
Recibe 2 parámetros:
Señal: contiene el número de señal que queremos capturar, en nuestro caso SIGUSR1. Si utilizaramos SIGKILL estaríamos utilizadon una señal para terminar procesos.
Func: contiene la función que queremos que se llame, es decir el manejador de la señal (signal handler). En el ejemplo definiremos un manejador para el proceso padre y otro para el hijo.
La función devolverá un puntero al manejador previamente instalado para esa señal. Un ejemplo de uso de la función: signal(SIGUSR1, gestion_padre); significa que cuando un proceso (el padre en este caso) recibe la señal SIGUSR1 debe realizar una llamda a la función gestion_padre().
Para enviar una señal utilizamos la función kill().
#include <signal.h>
int kill (int Pid, int Senyal);
Pid es el PID del proceso que recibe la señal y la propia señal.
kill(pid_hijo, SIGUSR1);
Los procesos pueden esperar con la función pause().
#include <unistd.h>
unsigned int sleep (unsigned int seconds);
sincronizar-1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
int main() {
int pid_hijo;
pid_hijo = fork();
switch(pid_hijo) {
case -1:
printf("Error al crear el prceso .. \n");
exit (-1);
case 0: //hijo
signal (SIGUSR1, manejador); // MANEJADOR DE LA SEÑAL EN HIJO
while(1) {
}
break;
default: // padre envía 2 señales
sleep(1);
kill (pid_hijo, SIGUSR1);
sleep (1);
kill (pid_hijo, SIGUSR1);
sleep (1);
break;
}
return 0;
}
void manejador(int sig) {
// haz algo
printf("He recibido la señal divina: %d\n",sig);
}
juanjo@ACER-JJ:~$ ./sincronizar-1
He recibido la señal divina: 10
He recibido la señal divina: 10
juanjo@ACER-JJ:~$
Un proceso padre se ejecutan de forma sincrona. Se definen dos funciones para gestionar la señal una para el padre y otro para el hijo, serán simplemente mensajes por pantalla.