Introduccion Posix Portable Operating System Interface Unix
Introduccion Posix Portable Operating System Interface Unix
Introduccion Posix Portable Operating System Interface Unix
Introducción
POSIX son un conjunto de normas IEEE/ISO que
definen la interfaz entre las aplicaciones y el SSOO
POSIX: Portable Operating System Interface + UniX
Su objetivo es conseguir la portabilidad de las
aplicaciones a nivel de código fuente
La aplicación puede desarrollarse en C, Ada,
Fortran y otros lenguajes
Las normas definen los servicios que cada sistema
operativo particular puede incluirlos o no
La denominación oficial es IEEE Std. 1003, e
ISO/IEC-9945
POSIX: estándares base (C)
POSIX 1, 1a Unix básico sin tiempo real
POSIX 1b, 1d, 1i, 1j Extensiones de tiempo real
POSIX 1c Extensiones de threads
POSIX 1e Seguridad
POSIX 1f Network File System
POSIX 1g Servicios de red (sockets)
POSIX 1h Tolerancia a fallos
POSIX 21 Comunicaciones de TR
POSIX: interfaz otros lenguajes
POSIX 5, 5a, 5b Interfaces con Ada
POSIX 9 Interfaces con Fortran 77
POSIX: perfiles de entornos
POSIX 10 Supercomputadores
POSIX 13 Tiempo real
POSIX 14 Multiprocesadores
POSIX 18 Estación de trabajo POSIX
POSIX de tiempo real ¿para qué?
Existe gran diversidad de sistemas de TR:
Núcleos de TR (LynxOS, VxWorks, QNX, etc.)
Ejecutivos Ada
En sistemas grandes: VMS y otros
Era necesario definir un estándar que asegurase la
portabilidad de aplicaciones a nivel de código fuente
entre diferentes entornos de tiempo real
Perfiles de entornos de aplicación
PSE50: sistema de tiempo real mínimo
Sólo procesos ligeros, sin gestión de memoria ni
archivos ni terminal
PSE51: controlador de tiempo real
Añade el terminal y sistema de archivos
PSE52: sistema de tiempo real dedicado
Soporta procesos pesados y gestión de memoria
PSE53: sistema de tiempo real generalizado
Sistema completo con todos los servicios
Características de los perfiles
Controlador SÍ NO SÍ
Sistema dedicado NO SÍ SÍ
Sistema multipropósito SÍ SÍ SÍ
POSIX: Unix básico
POSIX 1 define los servicios ofrecidos por Unix:
Gestión de procesos:
Creación y destrucción
Sincronización
Temporización
Gestión de archivos
Creación y borrado de archivos y directorios
Trabajo con archivos especiales
Protección de la información
Entrada-salida y control
POSIX: Extensiones de TR
Para obtener determinismo en el comportamiento
Planificación
Gestión de memoria
Señales
Relojes y temporizadores
Para facilitar la concurrencia
Sincronización
Memoria compartida
Colas de mensajes
Entrada-salida síncrona y asíncrona
POSIX: Extensiones de threads
POSIX 1c incorpora funciones para trabajar con
hilos. Incluye:
Gestión de hilos
Sincronización de hilos
Planificación de hilos
Creación y destrucción de hilos
Añade reentrada a algunas funciones de POSIX1
POSIX 1c puede hacer uso de funciones incluidas
en POSIX 1 y POSIX 1b
Definiciones
Programa
Archivo ejecutable residente en un dispositivo de
almacenamiento permanente
Se ejecuta por medio de la llamada exec()
Proceso
Es un programa en ejecución
Los procesos se crean con la llamada fork()
Funciones
main()
Núcleo
Ejemplo
/**************************************
* Programa que imprime todos los *
* argumentos de línea de órdenes *
**************************************/
int main (int argc, char *argv[])
{
int i;
for (i=0; i<argc; i++)
printf (“%s\n”, argv[i]);
exit(0);
} /* Fin de main */
Características de un proceso
Cada proceso se caracteriza por una estructura de
datos conocida como tabla de control de tarea que
contiene:
Identificador de proceso o PID
Identificador de proceso padre o PPID
Identificador de usuario o UID
Identificador de grupo o GID
Puntero a la memoria asignada
Puntero a los recursos ...
Cada proceso dispone de un espacio de
direccionamiento virtual independiente
Creación de procesos: fork()
Definida en:
#include <sys/types.h>
pid_t fork(void);
Valores de retorno:
Al padre: el PID del hijo
Al hijo: cero
En caso de error: devuelve -1 y la variable
errno contiene el valor asociado al error
Ejemplo con fork()
#include <sys/types.h>
int main(void) {
pid_t id;
id = fork();
if (id == -1) {
perror (“Error en el fork”);
exit (1);
}
if (id == 0) {
while (1) printf (“Hola: soy el hijo\n”);
} else {
while (1) printf (“Hola: soy el padre\n”);
}
} /* Fin de main */
Ejecución de programas: exec()
Definidos en:
#include <unistd.h>
int execl (const char *path,
const char *arg, ...);
int execlp (const char *file,
const char *arg, ...);
int execle (const char *path, const char *arg,
..., char * const envp[]);
int execv (const char *path, char const *argv[]);
int execvp (const char *file, char const *argv[]);
Valores de retorno:
En caso de error exec() devuelve -1
Ejemplo con exec()
#include <unistd.h>
int main(void) {
int ret;
char *arg[3];
arg[0] = “ls”;
arg[1] = “-l”;
arg[2] = (char *)0;
printf (“Allá va!\n”);
ret = execv (“/bin/ls”, arg);
if (ret == -1) {
perror (“Error en el exec”);
exit (1);
}
} /* Fin de main */
Finalización de procesos: exit()
int main(void) {
pid_t pid;
struct sched_param parametros;
int i, max_prio;
pid = getpid();
max_prio = sched_get_priority_max(SCHED_FIFO);
parametros.sched_priority = max_prio;
sched_setscheduler(pid, SCHED_FIFO, ¶metros);
for (i=0; i<100000000; i++);
} /* Fin de main */
Introducción
La memoria virtual introduce NO determinismo
POSIX proporciona la posibilidad de bloquear
memoria para evitar la aleatoriedad
Los procesos a pesar de tener un espacio de
direccionamiento disjunto pueden compartir objetos
de memoria
La compartición se realiza mapeando la zona de
memoria que deseamos compartir en los espacios
de direccionamiento virtuales de cada proceso
La compartición se realiza a través de páginas de
modo que el tamaño de una zona proyectada es un
múltiplo del tamaño de la página
Bloqueo de memoria
Los procesos pueden bloquear todas sus páginas
en memoria para evitar el intercambio con el disco
#include <sys/mman.h>
int mlockall (int flags);
El valor de flags puede ser:
MCL_CURRENT: afecta a las páginas actuales
MCL_FUTURE: afecta a las páginas futuras
Para liberar todas las páginas del proceso:
int munlockall (void);
Bloqueo de memoria
Un proceso pueden bloquear también un rango de
su espacio de direccionamiento
int mlock (const void *addr, size_t len);
Para desbloquear un rango de direcciones:
int munlock (const void *addr, size_t len);
Memoria compartida
Proceso 1 Proceso 2
Memoria física
M. Compartida
M. Compartida
M. Compartida
Proyección de objetos en memoria
La llamada mmap() permite proyectar objetos en
memoria
Estos objetos pueden ser compartidos
Función mmap():
void *mmap (void *addr, size_t len, int prot,
int flags, int fildes, off_t off);
El objeto queda identificado por fildes
len y off son la longitud y el offset del objeto en
bytes respectivamente
addr es la dirección donde deseamos proyectar el
objeto preferiblemente. Es sólo una indicación
Proyección de objetos en memoria
La dirección real donde se proyecta el objeto es
devuelta por mmap()y depende del valor de flags:
MAP_FIXED: addr se interpreta de forma exacta, sin este
flag si addr vale NULL, el sistema elige la
dirección
MAP_SHARED: los cambios son compartidos
MAP_PRIVATE: no se comparten los cambios
prot especifica el tipo de acceso:
PROT_READ: derecho de lectura
PROT_WRITE: derecho de escritura
PROT_EXEC: derecho de ejecución
PROT_NONE: sin derechos
Proyección de objetos en memoria
Para eliminar la proyección de un objeto en
memoria emplearemos la función munmap()
int munmap (void *addr, size_t len);
Objetos de memoria compartida
Para abrir un objeto de memoria compartida:
#include <sys/mman.h>
int shm_open (const char *path, int oflag,
mode_t mode );
Se establece una conexión entre el path que
identifica al objeto y el descriptor devuelto
oflag determina el modo de acceso
mode determina los derechos de acceso si creamos
un nuevo objeto
Es recomendable por razones de portabilidad que el
path comience con el carácter /
Objetos de memoria compartida
Fijar el tamaño de un objeto de memoria compartida
int ftruncate (int fildes, off_t length);
Para borrar un objeto de memoria compartida:
int shm_unlink (const char *path);