Los procesos existen en una jerarquía de árbol (varios Hijos, un sólo padre).
El sistema asigna un identificador de proceso (PID) único al iniciar el proceso.
El planificador de tareas asigna un tiempo compartido para el proceso según su prioridad (sólo root puede cambiar prioridades).
Ejecución en 1er plano:
proceso iniciado por el usuario o interactivo.
Ejecución en 2o plano:
proceso no interactivo que no necesita ser iniciado por el usuario.
Demonio:
proceso en 2o plano siempre disponible, que da servicio a varias tareas (debe ser propiedad del usuario root).
Proceso zombi:
proceso parado que queda en la tabla de procesos hasta que termine su padre. Este hecho se produce cuando el proceso padre no recoge el código de salida del proceso hijo.
Proceso huérfano:
proceso en ejecución cuyo padre ha finalizado. El nuevo identificador de proceso padre (PPID) coincide con el identificador del proceso init (1).
/* system.c - Listar los procesos del usuario usando system. */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int salida; /* Salida del comando */
char comando[100]; /* Comando a ejecutar */
printf ("Ejemplo de system.\n");
sprintf (comando, "/bin/ps -fu %s", getenv ("USER"));
salida = system (comando);
printf ("Salida del comando: %d\n", salida);
exit (salida);
}
Ejemplo de system.
USER PID PPID TTY CMD
ramon 3638 1 hft/0 -ksh
ramon 10089 10600 hfp/0 /bin/ps -fu ramon
ramon 10600 11623 hft/0 bsh bsh bsh
ramon 11623 3638 hft/0 system.e
Salida del comando: 0
Suponiendo que no existe el comando MUSHO y sustituyendo la ejecución de system por la siguiente línea, se obtiene la salida mostrada a continuación.
salida = system ("MUSHO BETI");
Ejemplo de system.
bsh: MUSHO: no encontrado.
Salida del comando: 256
Se crea un proceso imagen sustituyendo el programa actual por el nuevo.
- Formatos:
#include <unistd.h>
int execl (camino, arg0 [, arg1, ...] , 0)
const char *camino, *arg0, *arg1, ...;
int execle (camino, arg0 [, arg1, ...] , 0, p_entorno)
const char *camino, *arg0, *arg1, ...;
char *const p_entorno[];
int execlp (fichero, arg0 [, arg1, ...] , 0)
const char *fichero, *arg0, *arg1, ...;
int execv (camino, val_args)
const char *camino;
char *const val_args[];
int execve (camino, val_arg, p_entorno)
const char *camino;
char *const val_args[], *p_entorno[];
int execvp (fichero, val_args)
const char *fichero;
char *const val_args[];
int exect (camino, val_arg, p_entorno)
char *camino, *val_args, *p_entorno[];
- Sufijos:
L - usa lista de parámetros, el último debe ser 0.
V - usa matriz de parámetros generada previamente, el último debe ser 0.
T - trazado del programa con ptrace (en desuso).
E - usa la matriz de variables de entorno.
P - búsqueda utilizando la variable PATH.
- Parámetros:
camino - Camino completo del fichero ejecutable.
fichero - Nombre del fichero ejecutable.
argN - Argumento N-ésimo.
val_args - Puntero a la matriz de argumentos.
p_entorno - Puntero a la matriz del entorno.
- Devuelve:
-1, en caso de error.
- Comentarios:
a) La rutina principal (main) de un programa C ejecutable recibe los siguientes parámetros:
int main (cont_args, val_args, p_entorno)
int cont_args; /* Contador de argumentos. */
char *val_args; /* Puntero a la matriz de argumentos. */
char *p_entorno; /* Puntero a la matriz del entorno. */
Las variables val_args y p_entorno son similares a las utilizadas en las subrutinas exec.
b) Esta rutina principal llama a una subrutina de iniciación que construye la variable de entrono. Dicha variable global es accesible desde el programa declarándola de la siguiente manera:
extern char **environ;
Las subrutinas exec que no usan el parámetro p_entorno utilizan la variable environ.
c) Los descriptores de ficheros abiertos se pasan al nuevo proceso imagen, excepto los que tengan activo el bit FD_CLOEXEC (ver fcntl).
d) Las señales capturadas se reasignan a sus acciones por defecto; las ignoradas, continúan siendo ignoradas (ver sigaction).
e) Si el nuevo proceso imagen tiene activo el bit SUID, la identificación efectiva de usuario (EUID) del nuevo proceso toma el valor del identificador del propietario. Idem, si tiene activo el bit SGID.
f) Los identificadores reales de usuario y de grupo (RUID y RGID) mantienen el valor que tenían en el proceso llamador.
g) El párrafo anterior puede aplicarse a ficheros remotos (previa traducción de los identificadores).
h) El párrafo e) no afecta a las shell-scripts.
i) El proceso nuevo mantiene las siguientes características del proceso llamador:
Identificadores de proceso (PID), de proceso padre (PPID) y de grupo de procesos (PGID).
Valores de prioridad (nice), de TTY y del bit de trazado.
Directorio actual y directorio raíz.
Máscara de ficheros, limites de longitud de ficheros, límites de recursos.
Crea un nuevo proceso (hijo), copia casi exacta del proceso generador (padre).
- Formato:
#include <unistd.h>
pid_t fork ();
- Devuelve:
0 al proceso hijo y PID del hijo al proceso padre (-1, si error).
- Comentarios:
a) La versión BSD (en la librería libbsd.a) es:
int vfork ();
b) Atributos que hereda el proceso hijo.
Entorno.
Bit FD_CLOEXEC para cada descriptor de fichero.
Señales capturadas.
SUID y SGID.
Estado de privilegios y prioridades.
Librerías compartidas y segmentos de memoria compartida.
PGID y TTYGID.
Directorio actual y directorio raíz.
Máscara y límites de medida para ficheros.
Eventos y estado de auditoría.
Estado de depuración.
c) Atributos diferenciadores entre padre e hijo:
PID único.
PPID distintos (el PPID del hijo coincide con el PID del padre).
El proceso hijo tiene su propia copia de los descriptores de fichero del padre, pero comparte con éste un puntero a fichero para cada descriptor del proceso padre.
Bloqueos de proceso, texto y datos no se heredan.
Las subrutinas times se ponen a 0.
Las alarmas pendientes toman su valor inicial.
Se eliminan las señales pendientes para el proceso hijo.
/* fork.c - Ejecución conjunta de procesos padre e hijo */
#include <stdio.h>
#include <unistd.h>
main ()
{
printf ("Ejemplo de fork.\n");
printf ("Inicio del proceso padre. PID=%d\n", getpid ());
if (fork() == 0)
{ /* Proceso hijo */
printf ("Inicio proceso hijo. PID=%d, PPID=%d\n",
getpid (), getppid ());
sleep (1);
}
else
{ /* Proceso padre */
printf ("Continuación del padre. PID=%d\n", getpid ());
sleep (1);
}
printf ("Fin del proceso %d\n", getpid ());
exit (0);
}
Ejemplo de fork.
Inicio proceso padre. PID=8153
Inicio proceso hijo. PID=6618, PPID=8153
Continuación proceso padre. PID=8153
Fin del proceso 6618
Fin del proceso 8153
/* fork_huerf.c - Ejemplo de proceso huérfano *
#include <stdio.h>
#include <unistd.h>
main ()
{
printf ("Ejemplo de proceso huérfano.\n");
printf ("Inicio del proceso padre. PID=%d\n", getpid ());
if (fork () == 0)
{
printf ("Inicio proceso hijo. PID=%d, PPID=%d\n",
getpid (), getppid ());
sleep (1);
printf ("El proceso queda huérfano. PID=%d PPID=%d\n",
getpid (), getppid ());
}
else
printf ("Concinuación del padre. PID=%d\n", getpid ());
printf ("Fin del proceso %d\n", getpid ());
exit (0);
}
Ejemplo de proceso huérfano.
Inicio proceso padre. PID=11330
Inicio proceso hijo. PID=6467, PPID=11330
Continuación proceso padre. PID=11330
Fin del proceso 11330
$punto indicativo> El proceso queda huérfano. PID=6467, PPID=1
Fin del proceso 6467
Notas:
En el ejemplo, el proceso padre no espera la finalización del proceso hijo y termina antes que éste.
Cuando un proceso queda huérfano, el proceso de iniciación (init) se convierte en su padre.
Una vez que finaliza el proceso padre, se devuelve el control al intérprete de comandos, de ahí que aparezca el mensaje del "punto indicativo". El proceso hijo no deberá mandar mensajes a la consola, como ocurre en este ejemplo.
/* waitpid.c - Esperar la terminación de un proceso hijo */
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
main ()
{
pid_t id_padre; /* PID del proceso padre */
pid_t id_hijo; /* PID del proceso hijo */
int estado; /* Estado de salida */
printf ("Ejemplo de waitpid.\n");
printf ("Inicio proceso padre. PID=%d\n", getpid ());
id_padre = getpid ();
if ((id_hijo = fork ()) == 0)
{ /* Proceso hijo */
printf ("Inicio proceso hijo. PID=%d, PPID=%d\n",
getpid (), id_padre);
sleep (3);
printf ("Salida proceso hijo. PID=%d\n", getpid ());
exit (getpid () > id_padre); /* 1, si PID > PPID */
}
else
{
signal (SIGINT, SIG_IGN); /* Ignorar CTRL-C */
while (waitpid (id_hijo, &estado, 0) != id_hijo);
if (WIFSIGNALED (estado))
printf ("El proceso hijo ha recibido la señal %d\n", WTERMSIG (estado));
if (WIFEXITED (estado))
{
printf ("Estado de salida del proceso hijo: %d\n", WEXITSTATUS (estado));
if (WEXITSTATUS (estado) == 1)
printf ("PID hijo > PID padre.\n");
else
printf ("PID padre > PID hijo.\n");
}
printf ("Fin del proceso %d\n", getpid ());
exit (0);
}
Ejemplo de waitpid.
Inicio proceso padre. PID=24213
Inicio proceso hijo. PID=31638, PPID=24213
Fin proceso hijo. PID=31638
Estado de salida del proceso hijo: 1
PID hijo > PID padre
Fin del proceso 24213
La salida siguiente muestra el efecto de generar una señal de interrupción pulsando [CTRL][C]. Dicha señal provoca la terminación automática del proceso hijo, mientras que el proceso padre la ignora (ver signal).
Ejemplo de waitpid.
Inicio proceso padre. PID=7240
Inicio proceso hijo. PID=5705, PPID=7240
^CEl proceso hijo ha recibido la señal: 2
Fin del proceso 7240
a) El proceso de salida de un proceso es el siguiente:
Llamada a la función _cleanup para limpiar las áreas de E/S.
Llamada a la subrutina especificada en la subrutina atexit.
Llamada a la subrutina _exit para finalizar el proceso.
b) Si _cleanup no puede cancelar las peticiones de E/S asíncrona, la aplicación se bloquea hasta que se completen dichas peticiones.
c) Se cierran todos los descriptores de fichero.
d) Si el proceso padre está en espera (ver wait), se devuelve el valor de los 8 bits menos significativos del estado de salida.
e) Se envía una señal SIGCHLD al proceso padre. La acción por defecto es ignorar esta señal. Si no se ignora, el proceso hijo puede quedar como proceso zombi.
f) La salida de un proceso no provoca la terminación de sus hijos. El PPID de los hijos será el PPID del proceso init (1).
g) Se eliminan los bloqueos de ficheros (ver fcntl).
h) Si para un proceso perteneciente a un grupo huérfano, se envían las señales SIGHUP y SIGCONT a cada proceso del grupo de procesos huérfanos.
/* atexic.c - Ejecución de una rutina al salir de un programa */
#include <stdio.h>
#include <sys/limits.h>
int bucle=0; /* Contador de vueltas del bucle */
void salida (); /* Prototipo de la función de salida */
int main ()
{
int n;
atexit (salida);
printf ("Ejemplo de atexit.\n");
for (bucle=1; bucle<255; bucle++)
{
n=rand ();
printf ("%d-%d\t", bucle, n);
if (n > 30000)
exit (1);
}
exit (0);
}
void salida ()
{
printf ("El bucle ha dado %d vueltas.\n");
printf ("Hasta luega Lucas.\n");
}
Ejemplo de atexit.
1-16838 2-5758 3-10113 4-17515 5-31051
El bucle ha dado 5 vueltas.
Hasta luego Lucas.
/* signal.c - Contar el número de CTRL-C en 15 segundos */
#include <stdlib.h>
#include <signal.h>
int numcortes=0; /* Contador de CTRL-C */
int enbucle=1; /* Controlador de salida del bucle de espera */
void alarma (); /* Captura la señal de alarma SIGALRM */
void cortar (); /* Captura la señal de interrupción SIGINT */
int main ()
{
signal (SIGINT, cortar);
signal (SIGALRM, alarma);
printf ("Ejemplo de signal.\n");
printf ("Pulsa varias veces CTRL-C durante 15 segundos.\n");
alarm (15);
while (bucle);
signal (SIGINT, SIG_IGN);
printf ("Has intentado cortar %d veces.\n", numcortes);
printf ("Hasta luego Lucas.\n");
exit (0);
}
void alarma ()
{
signal (SIGALRM, SIG_IGN);
bucle=0; /* Salir del bucle */
printf ("¡Alarma!\n");
}
void cortar ()
{
signal (SIGINT, SIG_IGN);
printf ("Has pulsado CTRL-C\n");
numcortes++;
signal (SIGINT, cortar);
}
Ejemplo de signal.
Pulsa CTRL-C varias veces durante 15 segundo.
^CHas pulsado CTRL-C
^CHas pulsado CTRL-C
^CHas pulsado CTRL-C
^CHas pulsado CTRL-C
^CHas pulsado CTRL-C
¡Alarma!
Has intentado cortar 5 veces.
Hasta luego Lucas.
Especifica la acción a realizar cuando un proceso recibe una señal.
- Formato:
#include <signal.h>
int sigaction (señal, acción, acción_salida) ()
int señal;
struct sigaction *accón, *acción_salida;
- Parámetros:
señal: Número de señal, excepto SIGKILL.
acción: Acción especificada cuando se recibe la señal.
acción_salida: Acción a realizar cuando termine la función sigaction.
- Campos de la estructura sigaction:
void (*sa_handler) (); Puntero a la rutina asociada con la señal o uno de los valores:
SIG_DFL: acción por defecto para dicha señal.
SIG_IGN: ignorar la señal.
sigset_t sa_mask; Especifica la máscara de las señales que serán bloqueadas durante la captura de la señal especificada.
int sa_flags;
SA_ONSTACK: La captura de la señal se realiza en una pila de señales en vez de en la pila del proceso.
SA_OLDSTYLE: El parámetro señal se asocia con la ación por defecto (SIG_DFL) antes de llamar a la rutina de captura (no recomendable, la señal puede recurrir).
SA_NOCLDSTOP: Evita que el proceso padre reciba una señal SIGCHLD cuando para el proceso hijo.
- Devuelve:
0, si es correcta; -1, en caso de error.
- Comentarios:
a) Las siguientes funciones pueden ser llamadas sin problemas desde una rutina de captura de señales:
_exit
access
alarm
chdir
chmod
chown
close
creat
dup
dup2
exec
fcntl
fork
fstat
getegid
geteuid
getgid
getgroups
getpgrp
getpid
getppid
getuid
kill
link
lseek
mkdir
mkfifo
open
pause
pipe
readx
rename
rmdir
setgid
setpgrp
setuid
sigaction
sigaddset
sigdelset
sigfillset
sigismember
signal
sigpending
sigprocmask
sigsuspend
sleep
statx
tcdrain
tcflow
tcflush
tcgetattr
tcgetpgrp
tcsendbreak
tcsetattr
tcsetpgrp
time
times
umask
uname
unlink
ustat
utime
write
b) Una vez que una acción está instalada para una señal, continúa hasta que haya otra llamada a sigaction o se llame a la subrutina exec, excepto si se ha activado el bit SA_OLDSTYLE.
c) Las señales SIGKILL y SIGSTOP no pueden ser ignoradas.
c) Para enviar una señal a otro proceso deben coincidir el identificador de usuario (UID) real o efactivo de ambos procesos, o que el proceso emisor tenga prioridad de usuario root.
/* kill.c - Ejecución con tiempo de espera usando kill */
#include <stdlib.h>
#include <signal.h>
int espera; /* Tiempo de espera */
void hijo (); /* Controlador de fin de proceso hijo */
int main (int contargs, char *args[]);
{
pid_t pid;
if (contargs < 3)
{
printf ("Formato: %s segundos comando [opciones].\n", args[0]);
exit (1);
}
printf ("Ejemplo de kill.\n");
printf ("Ejecución con tiempo de espera.\n");
signal (SIGCHLD, hijo);
pid = fork ();
if (pid == 0)
{
execvp (args[2]; &args[2]);
perror (args[0]);
}
else
{
espera = atoi (args[1]);
sleep (espera);
printf ("El hijo %d ha excedido el tiempo de %d s.\n",
pid, espera);
signal (SIGCHLD, SIG_IGN);
kill (pid, SIGINT);
}
exit (1);
}
void espera ()
{
int id_hijo, est_hijo;
id_hijo = wait (&est_hijo);
printf ("El hijo %d ha terminado antes de %d s.\n",
id_hijo, espera);
exit (0);
}
$ kill.e 3 wc kill.c
Ejemplo de kill.
Ejecución de un comando con tiempo de espera.
45 132 1065 kill.c
El hijo 10489 ha terminado antes de 3 s.
$ kill.e 3 sleep 5
Ejemplo de kill.
Ejecución de un comando con tiempo de espera.
El hijo 10851 ha excedido el tiempo de espera de 3 s.
Genera alarmas de reloj (señal SIGALRM) para el proceso actual.
- Formato
#include <unistd.h>
unsigned int alarm (segundos)
unsigned int segundos;
unsigned int ualarm (valor, intervalo)
unsigned int valor, intervalo;
- Parámetros:
segundos: Número de segundos para enviar al proceso la señal SIGALRM.
valor: Número de señales generadas.
intervalo: Intervalo (en ms.) entre las señales.
- Devuelve:
alarm devuelve el número de segundos que restan para generar la señal.
ualarm devuelve el número de microsegundos que restan hasta la próxima señal.
- Comentarios:
a) Sólo puede generarse una única alarma (no son aplilables).
b) El parámetro intervalo no puede ser menor que 10 para un usuario sin privilegios.
c) Estas 2 subrutinas son compatibles con las primeras versiones del AIX, con UNIX System V y con UNIX de Berkeley (BSD). En AIX, se han programado como llamadas a la subrutina incinterval.
/* alarm.c - Esperar una alarma */
#include <stdlib.h>
#include <unistd.h>
int main ()
{
printf ("Una alarma en 3 segundos.\n");
alarm (3);
printf ("Esperando...\n");
while (1);
printf ("Esta línea no se ejecutará nunca.\n");
exit (0);
}
Una alarma en 3 segundos.
Esperando...
Alarm clock
Número entero positivo usado por un proceso para identificar un fichero abierto. Esta traducción se realiza mediante una tabla de descriptores de fichero, ubicado en la zona de datos del proceso.
Descriptores reservados:
0: entrada normal (stdin).
1: salida normal (stdout).
2: salida de error (stderr).
Redirección:
Establecer copias del descriptor de ficheros de un archivo para encauzar las operaciones de E/S hacia otro fichero.
Tubería:
Mecanismo de intercomunicación entre procesos que permite que 2 o más procesos envíen información a cualquier otro.
Tubería sin nombre:
Enlace de comunicación unidireccional, capaz de almacenar su entrada (hasta 4 KB en BSD o hasta 40 KB en System V).
Tuberías nombradas (FIFO):
Permiten una comunicación menos restringida, ya que las colas FIFO existen en el sistema de archivos hasta que son borradas.
Características:
Permite comunicar procesos no emparentados.
Tiene una entrada en el sistema de archivos.
Usa una política de colas "primero en llegar, primero en servirse".
Realiza operaciones de control sobre ficheros abiertos, tales como:
duplicar el descriptor,
poner o leer características del descriptor,
poner o leer estado del fichero,
gestionar bloqueos de registros,
gestionar la propiedad de la E/S asíncrona,
cerrar varios ficheros.
- Formato:
#include <unistd.h>
#include <fcntl.h>
#include <sys/types>
int fcntl (descriptor, comando, argumento)
int descriptor, comando, argumento);
- Parámetros:
descriptor: Descriptor del fichero.
comando: Operación ha realizar.
argumento: Parámetro del comando.
- Devuelve:
Valor devuelto por el comando; -1, en caso de error.
- Operaciones:
F_DUPFD:
Obtener el menor descriptor de fichero disponible que sea mayor que el parámetro descriptor. Mantiene el mismo puntero y las mismas características del fichero original.
F_GETFD:
Obtener características del descriptor.
F_SETFD:
Poner características del descriptor.
F_GETFL:
Obtener estado del fichero.
F_SETFL:
Poner estado del fichero.
F_GETLK:
Obtener información de bloqueo.
F_SETLK:
Poner bloqueo.
F_SETLKW:
Poner bloqueo en una zona bloqueada.
F_GETOWN:
Obtener PID (>0) o PGID (<0) del proceso que recibe las señales SIGIO o SIGURG.
F_SETOWN:
Poner PID (>0) o PGID (<0) del proceso gestor de la E/S asíncrona.
F_CLOSEM:
Cierra todos los descriptores desde descriptor hasta el valor máximo (OPEN_MAX).
- Características del descriptor de ficheros:
FD_CLOEXEC: Indica si el descriptor se cerrará ante una función exec.
- Estados del modo de acceso al fichero:
O_RDONLY:
Abierto sólo para lectura.
O_RDWR:
Abierto para lectura y escritura.
O_WRONLY:
Abierto sólo para escritura.
- Bloqueos:
F_RDLCK:
Bloqueo de lectura (compartido).
F_WRLCK:
Bloqueo de escritura (exclusivo).
F_UNLCK:
Sin bloqueo.
- Comentarios:
a) Un bloqueo de lectura evita que otros procesos activen bloqueos de lectura en cualquier zona del área protegida. Sí se permiten otros bloqueos de lectura en toda el área o en partes de ella.
b) Un bloqueo de escritura evita que otros procesos bloqueen dicha zona.
c) Los "abrazos mortales" en un sistema distribuido no siempre son detectables. El programa deberá usar temporizadores para poder liberar sus bloqueos.
Crea un canal de comunicación entre procesos emparentados.
- Formato:
#include <unistd.h>
int pipe (descriptores)
int descriptores[2];
- Parámetros:
Tabla que recibirá los descriptores de entrada y de salida de la tubería.
- Devuelve:
0, si se ha completado correctamente; -1, en caso de error.
- Comentarios:
a) descriptores[0] se abre para lectura y descriptores[1], para escritura.
b) La operación de lectura en descriptores[0] accede a los datos escritos en descriptores[1] como en una cola FIFO (primero en llegar, primero en servirse),
/* pipe.c - Tubería sin nombre entre procesos padre e hijo */
#include <stdlib.h>
#include <unistd.h>
#define LEER 0
#define ESCRIBIR 1
int main ()
{
int descr[2]; /* Descriptores de E y S de la turbería */
int bytesleidos;
char mensaje[100],
*frase="Veremos si la transferecia es buena.";
printf ("Ejemplo de tuberÍa entre padre e hijo.\n");
pipe (descr);
if (fork () == 0)
{
close (descr[LEER]);
write (descr[ESCRIBIR], frase, strlen(frase));
close (descr[ESCRIBIR]);
}
else
{
close (descr[ESCRIBIR]);
bytesleidos = read (descr[LEER], mensaje, 100);
printf ("Bytes leidos: %d\n");
printf ("Mensaje: %s\n", bytesleidos, mensaje);
close (descr[LEER]);
}
}
Ejemplo de tubería entre padre e hijo.
Bytes leídos: 36
Mensaje: Veremos si la transferencia es buena.
/* pipe_conec.c - Tubería entre 2 comandos usando pipe. */
#include <stdlib.h>
#include <unistd.h>
#define LEER 0
#define ESCRIBIR 1
int main (int contargs, char *args[])
{
int descr[2]; /* Descriptores de E y S de la turbería */
if (contargs != 3)
{
printf ("Formato: %s comando_ent comando_sal.\n", args[0]);
exit (1);
}
pipe (descr);
if (fork () == 0)
{
close (descr[LEER]);
dup2 (descr[ESCRIBIR], 1);
close (descr[ESCRIBIR]);
execlp (args[1], args[1], NULL);
perror (args[0]);
}
else
{
close (descr[ESCRIBIR]);
dup2 (descr[LEER], 0);
close (descr[LEER]);
execlp (args[2], args[2], NULL);
perror (args[0]);
}
}
/* lector_fifo.c - Tuberia con nombre usando mkfifo */
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mode.h>
int linea (int df, char *cad);
int main ()
{
int descr;
char cadena[100];
unlink ("tuberia");
mkfifo ("tuberia", 0);
chmod ("tuberia", 460);
descr = open ("tuberia", O_RDONLY);
while (linea (descr, cadena))
printf ("%s\n", cadena);
close (descr);
pritnf ("Fin del lector.\n");
}
int linea (int df, char *cad)
{
int n;
do
{
n = read (df, cad, 1);
}
while (n > 0 && *cad++ != NULL);
return (n > 0);
}
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mode.h>
int main ()
{
int descr, longmens, i;
char mensaje[100];
sprintf (mensaje, "Un saludo desde el proceso %d", getpid ());
longmens = strlen (mensaje) + 1;
do
{ /* intentar la conexion */
descr = open ("tuberia", O_WRONLY);
if (descr == -1) sleep (1);
}
while (descr == -1);
for (i=0; i<3; i++)
{
write (descr, mensaje, longmens);
sleep (3);
}
close (descr);
printf "Fin del escritor %d\n", getpid ());
}
#!/bin/ksh
# fifo - Carga los procesos lector y escritor en 2o plano.
lector_fifo.e &
escritor_fifo.e &
escritor_fifo.e &
$ fifo
$Un saludo desde el proceso 11996
Un saludo desde el proceso 10971
Un saludo desde el proceso 11996
Un saludo desde el proceso 10971
Un saludo desde el proceso 11996
Un saludo desde el proceso 10971
Fin del escritor 10971
Fin del escritor 11996
Fin del lector
-Món en la Telaraña.
A much more important factor in the social movement than those already mentioned was the ever-increasing influence of women. This probably stood at the lowest point to which it has ever fallen, during the classic age of Greek life and thought. In the history of Thucydides, so far as it forms a connected series of events, four times only during a period of nearly seventy years does a woman cross the scene. In each instance her apparition only lasts for a moment. In three of the four instances she is a queen or a princess, and belongs either to the half-barbarous kingdoms of northern Hellas or to wholly barbarous Thrace. In the one remaining instance208— that of the woman who helps some of the trapped Thebans to make their escape from Plataea—while her deed of mercy will live for ever, her name is for ever lost.319 But no sooner did philosophy abandon physics for ethics and religion than the importance of those subjects to women was perceived, first by Socrates, and after him by Xenophon and Plato. Women are said to have attended Plato’s lectures disguised as men. Women formed part of the circle which gathered round Epicurus in his suburban retreat. Others aspired not only to learn but to teach. Arêtê, the daughter of Aristippus, handed on the Cyrenaic doctrine to her son, the younger Aristippus. Hipparchia, the wife of Crates the Cynic, earned a place among the representatives of his school. But all these were exceptions; some of them belonged to the class of Hetaerae; and philosophy, although it might address itself to them, remained unaffected by their influence. The case was widely different in Rome, where women were far more highly honoured than in Greece;320 and even if the prominent part assigned to them in the legendary history of the city be a proof, among others, of its untrustworthiness, still that such stories should be thought worth inventing and preserving is an indirect proof of the extent to which feminine influence prevailed. With the loss of political liberty, their importance, as always happens at such a conjuncture, was considerably increased. Under a personal government there is far more scope for intrigue than where law is king; and as intriguers women are at least the209 equals of men. Moreover, they profited fully by the levelling tendencies of the age. One great service of the imperial jurisconsults was to remove some of the disabilities under which women formerly suffered. According to the old law, they were placed under male guardianship through their whole life, but this restraint was first reduced to a legal fiction by compelling the guardian to do what they wished, and at last it was entirely abolished. Their powers both of inheritance and bequest were extended; they frequently possessed immense wealth; and their wealth was sometimes expended for purposes of public munificence. Their social freedom seems to have been unlimited, and they formed combinations among themselves which probably served to increase their general influence.321 The old religions of Greece and Italy were essentially oracular. While inculcating the existence of supernatural beings, and prescribing the modes according to which such beings were to be worshipped, they paid most attention to the interpretation of the signs by which either future events in general, or the consequences of particular actions, were supposed to be divinely revealed. Of these intimations, some were given to the whole world, so that he who ran might read, others were reserved for certain favoured localities, and only communicated through the appointed ministers of the god. The Delphic oracle in particular enjoyed an enormous reputation both among Greeks and barbarians for guidance afforded under the latter conditions; and during a considerable period it may even be said to have directed the course of Hellenic civilisation. It was also under this form that supernatural religion suffered most injury from the great intellectual movement which followed the Persian wars. Men who had learned to study the constant sequences of Nature for themselves, and to shape their conduct according to fixed principles of prudence or of justice, either thought it irreverent to trouble the god about questions on which they were competent to form an opinion for themselves, or did not choose to place a well-considered scheme at the mercy of his possibly interested responses. That such a revolution occurred about the middle of the fifth century B.C., seems proved by the great change of tone in reference to this subject which one perceives on passing from Aeschylus to Sophocles. That anyone should question the veracity of an oracle is a supposition which never crosses the mind of the elder dramatist. A knowledge of augury counts among the greatest benefits222 conferred by Prometheus on mankind, and the Titan brings Zeus himself to terms by his acquaintance with the secrets of destiny. Sophocles, on the other hand, evidently has to deal with a sceptical generation, despising prophecies and needing to be warned of the fearful consequences brought about by neglecting their injunctions. The stranger had a pleasant, round face, with eyes that twinkled in spite of the creases around them that showed worry. No wonder he was worried, Sandy thought: having deserted the craft they had foiled in its attempt to get the gems, the man had returned from some short foray to discover his craft replaced by another. “Thanks,” Dick retorted, without smiling. When they reached him, in the dying glow of the flashlight Dick trained on a body lying in a heap, they identified the man who had been warned by his gypsy fortune teller to “look out for a hidden enemy.” He was lying at full length in the mould and leaves. "But that is sport," she answered carelessly. On the retirement of Townshend, Walpole reigned supreme and without a rival in the Cabinet. Henry Pelham was made Secretary at War; Compton Earl of Wilmington Privy Seal. He left foreign affairs chiefly to Stanhope, now Lord Harrington, and to the Duke of Newcastle, impressing on them by all means to avoid quarrels with foreign Powers, and maintain the blessings of peace. With all the faults of Walpole, this was the praise of his political system, which system, on the meeting of Parliament in the spring of 1731, was violently attacked by Wyndham and Pulteney, on the plea that we were making ruinous treaties, and sacrificing British interests, in order to benefit Hanover, the eternal millstone round the neck of England. Pulteney and Bolingbroke carried the same attack into the pages of The Craftsman, but they failed to move Walpole, or to shake his power. The English Government, instead of treating Wilkes with a dignified indifference, was weak enough to show how deeply it was touched by him, dismissed him from his commission of Colonel of the Buckinghamshire Militia, and treated Lord Temple as an abettor of his, by depriving him of the Lord-Lieutenancy of the same county, and striking his name from the list of Privy Councillors, giving the Lord-Lieutenancy to Dashwood, now Lord Le Despencer. "I tell you what I'll do," said the Deacon, after a little consideration. "I feel as if both Si and you kin stand a little more'n you had yesterday. I'll cook two to-day. We'll send a big cupful over to Capt. McGillicuddy. That'll leave us two for to-morrer. After that we'll have to trust to Providence." "Indeed you won't," said the Surgeon decisively. "You'll go straight home, and stay there until you are well. You won't be fit for duty for at least a month yet, if then. If you went out into camp now you would have a relapse, and be dead inside of a week. The country between here and Chattanooga is dotted with the graves of men who have been sent back to the front too soon." "Adone do wud that—though you sound more as if you wur in a black temper wud me than as if you pitied me." "Wot about this gal he's married?" "Don't come any further." "Davy, it 'ud be cruel of us to go and leave him." "Insolent priest!" interrupted De Boteler, "do you dare to justify what you have done? Now, by my faith, if you had with proper humility acknowledged your fault and sued for pardon—pardon you should have had. But now, you leave this castle instantly. I will teach you that De Boteler will yet be master of his own house, and his own vassals. And here I swear (and the baron of Sudley uttered an imprecation) that, for your meddling knavery, no priest or monk shall ever again abide here. If the varlets want to shrieve, they can go to the Abbey; and if they want to hear mass, a priest can come from Winchcombe. But never shall another of your meddling fraternity abide at Sudley while Roland de Boteler is its lord." "My lord," said Edith, in her defence, "this woman has sworn falsely. The medicine I gave was a sovereign remedy, if given as I ordered. Ten drops would have saved the child's life; but the contents of the phial destroyed it. The words I uttered were prayers for the life of the child. My children, and all who know me, can bear witness that I have a custom of asking His blessing upon all I take in hand. I raised my eyes towards heaven, and muttered words; but, my lord, they were words of prayer—and I looked up as I prayed, to the footstool of the Lord. But it is in vain to contend: the malice of the wicked will triumph, and Edith Holgrave, who even in thought never harmed one of God's creatures, must be sacrificed to cover the guilt, or hide the thoughtlessness of another." "Aye, Sir Treasurer, thou hast reason to sink thy head! Thy odious poll-tax has mingled vengeance—nay, blood—with the cry of the bond." HoME古一级毛片免费观看
ENTER NUMBET 0017 pdjnew.com.cn tegui5.net.cn daiwo9.com.cn www.zizhuyan.com.cn www.sysusan.com.cn www.qpaw.com.cn www.sikou0.com.cn maofu7.net.cn www.duota7.com.cn www.85tattoo.com.cn