Entender los mecanismos básicos de unix para comunicar y sincronizar procesos entre sí y con el mundo exterior.
Compile el programa psignal.c:
/* psignal.c */
#include <unistd.h>
#include <signal.h>
void confirmar(int sig) {
char resp[100];
write(1, "¿Quiere terminar? (s/n):", 24);
read(0, resp, 100);
if (resp[0]=='s') exit(0);
signal(SIGINT, confirmar);
}
int main(void) {
int i, j;
signal(SIGINT, SIG_IGN);
for (i=0; i<10; i++) {
write(1, "No hago caso a ^C\n", 18);
for (j = 0; j < 10000000; j++);
}
signal(SIGINT, SIG_DFL);
for (i=0; i<10; i++) {
write(1, "Ya hago caso a ^C\n", 18);
for (j = 0; j < 10000000; j++);
}
signal(SIGINT, confirmar);
for (i=0; i<10; i++) {
write(1, "Ahora lo que digas\n", 19);
for (j = 0; j < 10000000; j++);
}
exit(0);
}
y ejecútelo, intentando abortarlo en varios momentos con
CONTROL-C. Ejecútelo con strace
y observe que
signal
no es una llamada al sistema, sino una rutina de
biblioteca que llama a sigaction
.
Ejecute el programa esignal.c para observar que las señales transmiten información, aunque sea de forma rudimentaria.
/* esignal.c */
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void productor(int pid) {
int i;
for (i=1; i<=5; i++) {
sleep(5);
kill(pid, i);
}
sleep(5);
kill(pid, SIGKILL);
exit(0);
}
void atiende(int sig) {
printf("Recibida %d\n", sig);
}
void consumidor(void) {
int i;
for (i=1; i<=5; i++)
signal(i, atiende);
for (;;) {
write(1, ".", 1);
sleep(1);
}
}
int main(void) {
int pid;
if ((pid= fork())==0)
consumidor();
else
productor(pid);
}
Ejecute el programa pipe.c, para observar como el productor y el consumidor se intercambian información:
/* pipe.c */
#include <unistd.h>
#include <stdio.h>
void productor(int esc) {
int i;
for (i=1; i<=10; i++) {
write(esc, &i, sizeof i);
sleep(1);
}
exit(0);
}
void consumidor(int lec) {
int leidos, i;
while ((leidos = read(lec, &i, sizeof i)) > 0) {
printf("Recibido %d\n", i);
}
exit(0);
}
int main(void) {
int pid, tubo[2];
pipe(tubo);
if ((pid= fork())==0) {
close(tubo[1]);
consumidor(tubo[0]);
}
else {
close(tubo[0]);
productor(tubo[1]);
}
}
Modifique el programa de copia de ficheros realizado por un proceso
hijo para que el padre saque un punto por la salida estándar por
cada segundo que pase. Úsese sleep
o alarm
para
controlar el tiempo. El programa principal terminará al recibir la señal
SIGCHLD
, cuando el hijo termine.
Modifique el programa de copia de ficheros para que la lectura la haga un proceso y la escritura otro, comúnicándose a través de un pipe.