-
Notifications
You must be signed in to change notification settings - Fork 1
/
introduccion.tex
247 lines (188 loc) · 15.6 KB
/
introduccion.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
\documentclass[12pt, letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{fancyhdr}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{hyperref}
\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
\hypersetup{
colorlinks=true,
linkcolor=blue,
filecolor=magenta,
urlcolor=cyan,
pdftitle={Sharelatex Example},
bookmarks=true,
pdfpagemode=FullScreen,
}
\lstdefinestyle{mystyle}{
backgroundcolor=\color{backcolour},
commentstyle=\color{codegreen},
keywordstyle=\color{magenta},
numberstyle=\tiny\color{codegray},
stringstyle=\color{codepurple},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2
}
\lstset{style=mystyle}
\title{Sistemas Operativos}
\author{David Lopez}
\date
\pagestyle{fancy}
\fancyhf{}
\rhead{David Lopez}
\lhead{Sistemas operativos}
\rfoot{\thepage}
\begin{document}
\begin{titlepage}
\clearpage\maketitle
\thispagestyle{empty}
\end{titlepage}
\tableofcontents{}
\section{conceptos basicos}
Un sistema operativo no es mas que un progama.
\subsection{Funciones del s.o}
Este programa, no obstante, es bastante caracteristico, pues se encarga de \textbf{gestionar los recursos hardware}, ofrece a los demas programas una api de \textbf{llamadas al sistema} y proporciona \textbf{mecanismos de interaccion con el usuario} como el shell.\par
Es necesario gestionar los recursos hardware por que podemos tener varios programas ejecutandose a la vez, y se hace mas importante con los sistemas multiusuario. Los programas competiran por los recursos, por lo que sera necesario administrarlos correctamente.\par
Sobre las llamadas al sistema habra algunos ejercicios para familiarizarnos, hay que tener en cuenta, que a diferencia de un curso de desarrollo sobre el kernel de un sistema operativo, aqui nos centraremos en programas de espacio de usuario y nos limitaremos, al menos por el momento a invocar a estas llamadas, no a implementarlas en incluirlas en el s.o , cosa que tambien se puede hacer.
\subsection{partes principales del s.o}
Podemos distinguir tres partes principales: \textbf{nucleo o kernel, servicios e interfaz de usuario}
\subsection{clasificacion segun su estructura}
\begin{itemize}
\item{Monolitico (como linux): Tiene todos los componentes integrados en un mismo programa}
\item{Por capas: cada capa ofrece una interfaz a la capa siguiente}
\item{Cliente-Servidor (microkernel): el kernel se reduce a la minima expresion y el resto de utilidades se desarrollan en proceso de usuario}
\end{itemize}
\subsection{Como lo usamos ?}
Podemos poner el sistema operativo a trabajar, deliberadamente y para que haga la funcion que queremos, escribiendo un programa que realize llamadas al sistema, las interrupciones de los perifericos y los errores tambien provocara la activacion del s.o
\subsection{ejemplo de programa que invoca llamadas al sistema}
\textit{escribir una funcion en C, que actue como el comando cat de unix, es decir, que imprima el contenido del archivo por la salida estandar}
\lstinputlisting[language=C]{cat.c}
En este codigo, las funciones \textit{open, read, write y close} son llamadas al sistema, cuyo man se puede encontrar en: \href{http://man7.org/linux/man-pages/man2/}{manual de llamadas al sistema}, es fundamental saber utilizar esta herramienta y manejar con solvencia las llamadas al sistema mas habituales.
\section{Archivos y directorios}
\subsection{Conceptos basicos de archivos}
El sistema operativo nos oculta los detalles de la implementacion fisica del disco, proporcionandonos lo que conocemos como archivo.\par
\textit{Que es un archivo: Es una unidad de almacenamiento logico \textbf{no volatil} que agrupa un conjunto de informacion relacionada entre si bajo un mismo nombre}\par
Carateristicas de un archivo:
\begin{itemize}
\item Desde el punto de vista de el sistema operativo este debe proporcionar al menos una estructura de archivo que permita realizar sobre el: darle nombre, proteccion y sistema eficiente de gestion de estos mismos. Ademas debe permitir anadirle los atributos que se deseen.
\item El nombre y extension son basicos para un archivo y deben permitir que se le distinga inequivocamente
\item El usuario debe percibir sencillez para manipular archivos. La traduccion entre las direcciones fisicas y logicas es lo que depende segun el sistema operativo pero se basa en el \textbf{mapa de archivos} que se almacena como atributo.
\item Se distinguen dos tipos principales de acceso a la informacion en los archivos: \textbf{Secuencial}, si todos los bytes estan seguidos y en orden o \textbf{acceso aleatorio o directo} que permiten el acceso por conjuntos y desordenado.
\item Cuando se accede de forma concurrente al mismo archivo, se establecen mecanismos tipicos para tratar la concurrencia: Archivos inmutables, sesiones(copias y versiones) y UNIX(cada proceso trabaja con su imagen independiente del archivo y no se permite que compartan el apuntador.)
\end{itemize}
\subsection{Conceptos basicos de directorios}
Para poder acceder a los archivos con facilidad, se crean formas de organizar los nombres de los archivos, son los directorios.
\textit{Que es un directorio: Es un objeto que relaciona el nombre del usuario de un archivo y el descriptor interno del mismo.}
Caracteristicas de los directorios:
\begin{itemize}
\item Actualmente los sistemas operativos se organizan en forma de arbol, que representa los directorios y subdirectorios partiendo de una raiz de forma que existe un unico camino a un archivo.
\item Para solventar la problematica de que varios usuarios quieran trabajar sobre el mismo archivo (pero tienen rutas hasta el distintas), se generaliza de arbol a grafo aciclico.
\item La forma mas habitual de compartir archivos es crear un \textbf{enlace} , que puede ser fisico o simbolico. La diferencia es que mientras que uno apunta al mismo archivo el otro crea una copia de los contenidos en uno nuevo.
\item En UNIX se utilizan los \textbf{i-nodos} para saber cuantos enlaces fisicos tiene un mismo archivo. Esto provoca que haya que controlar los bucles al recorrer todo el arbol e introduce problemas al borrarlos (se solventa disminuyendo el contador, y hasta que no sea 0, no se borra del todo)
\item Cuando estamos trabajando desde algun directorio y nos queremos mover o referir a otro directorio o archivo, el sistema operativo ha de tener en cuenta que las \textbf{referencias} que hagamos pueden ser \textbf{absolutas (desde la raiz)} o \textbf{relativas}. Ver ls -a . y ..
\end{itemize}
\subsection{Servicios de archivos y directorios}
Cuando abrimos un archivo, lo que obtenemos es un \textbf{descriptor de archivo} que en UNIX se conoce como \textbf{i-nodo}. Por ejemplo, para la salida estandar hay unos descritores fijos: 0-in, 1-out, 2-err. Los inodos contienen todos los atributos que nos interesaran para nuestro estudio.\par
Permisos de acceso: bits: setuid(ejecutable-user), setgid(ejecutable-grupo), rwx(user), rwx(grupo), rwx(resto). \par
Servicios POSIX para ficheros:
\begin{itemize}
\item Crear y abrir un fichero: \texttt{int creat(const char * path, mode\_t mode);}
\item Borrar un fichero por su ruta: \texttt{int ulink(const char * path);}
\item Abrir un fichero por su ruta en un determinado modo: \texttt{int open(const char path, int oflag, mode\_t mode);}
\item Cerrar un fichero por su descriptor (devuelto por alguna de las funciones anteriores): \texttt{int close(int fd);}
\item Leer \textbf{nbytes} de un archivo a \textbf{buf}: \texttt{ssize\_t read(int fd, void *buf, size\_t nbytes);}
\item Escribir \textbf{nbytes} de \textbf{buf} a un archivo: \texttt{ssize\_t write(int fd, const void *buf, size\_t nbytes);}
\item Mover el apuntador de posiciono de un archivo \textbf{offset} desde \textbf{whence} que puede tomar los valores: SEEK\_SET (inicio), SEEK\_CURR (posicion actual) y SEEK\_END: \texttt{off\_t lseek(int fd, off\_t offset, int whence);}
\item Consultar atributos de un archivo: \texttt{ int stat(const char *path, struct stat *buf);} , devuelven una estructura de tipo stat (ver esta estructura para saber que atributos podemos obtener a partir de esta llamada)
\end{itemize}
Servicios POSIX para directorios:
\begin{itemize}
\item Crear un directorio: \texttt{ int mkdir(const char * path, mode\_t mode)}
\item Borrar un directorio ( solo se puede borrar si esta vacio ): \texttt{ int rmdir(const char * path)}
\item Abrir un directorio: \texttt{ DIR * opendir(const char * pathname)}
\item Cerrar un directorio: \texttt{ int closedir(DIR * dirp);}
\item Leer la siguiente entrada de un directorio (nombre del archivo e i-nodo): \texttt{struct dirent *readdir(DIR * dirp);}
\item Comprobar si un archivo en un directorio esta accesible con unos ciertos permisos: \texttt{int access( const char * path, int amode );}
\item Cambiar los permisos sobre un archivo: \texttt{int chmod(const char * path, mode\_t mode);}
\item Cambiar el propietario y el grupo de un archivo: \texttt{ int chown(const char * path, uid\_t owner, gid\_t group);}
\item Definir una mascara que sera aplicada por defecto a todos los objetos de un usuario: \texttt{ mode\_t umask(mode\_t cmask);}
\item Establecer un enlace fisico entre una nueva entrada de directorio y un archivo ya existente: \texttt{ int link(const char * existing, const char * new);}
\item Establecer un enlace simbolico desde una nueva entrada de directorio a un archivo ya existente: \texttt{ int symlink( const char * existing, const char * new);}
\end{itemize}
\section{Procesos}
\subsection{Conceptos basicos}
Un proceso es la unidad de procesamiento gestionada por el sistema operativo.\par
El sistema operativo mantiene una tabla de procesos. En esta tabla se almacena un \textbf{bloque de control de proceso} \textit{(estructura \href{https://github.com/torvalds/linux/blob/master/include/linux/sched.h}{task\_struct} en linux)} por cada proceso.
El BCP contiene la siguiente informacion:
\begin{itemize}
\item{Identifiacion: PID, USER y relaciones padre-hijo}
\item{Estado del procesador}
\item{Informacion de control del proceso}
\item{Memoria asignada}
\item{Recursos asignados}
\end{itemize}
\subsection{threads}
Un determinado proceso puede comenzar a crear hilos y por tanto a desdoblarse, esto implica que la imagen de memoria del proceso original se va a compartir entre desitintos procesos, la imagen de memoria no se replica como en el fork. De esta forma conseguimos una ventaja importante con respecto a los recursos del sistema. Lo que se comparte y no se comparte, se explica mas abajo.\par
Un proceso puede contener varios threads, o hilos de ejecucion que comparten algunos recursos e informacion entre ellos.\par
Cada thread se define como una funcion que se puede lanzar en paralelo con otras.\par
Los threads del mismo proceso comparten parte de su informacion: Memoria, variables globales, archivos abiertos, procesos hijos, temporizadores y semaforos. Que compartan la memoria genera que no haya proteccion de memoria y los threads son independientes unos de otros hasta cierto punto.\par
Pero no comparten: contador de programa, pila, registros y estado. En resumen, el contexto de ejecucion.\par
Las ventajas que proporciona este mecanismo de "dividir el trabajo de los procesos en tareas mas sencillas" es claro y sigue el paradigma de divide y venceras, sin embargo, cuando entramos en el terreno de la programacion concurrente hemos de ser cuidadosos por los tipicos problemas que pueden surgir.\par
\subsection{senales}
Se puede describir una senal como una interrupcion a un proceso. El comportamiento de las senales es similar al de las interrupciones en la cpu.\par
Las senales pueden provenir o bien de un proceso que la manda a otro proceso con su mismo \textit{uid} o el sistema operativo ante las tipicas excepciones que vemos cuando fallan nuestros programas (seg fault, /0...)\par
Hay muchas senales diferentes y se engloban en tres tipos fundamentales: De hardware, de comunicacion y de E/S asincrona.\par
Para que un proceso pueda enviar una senal ha de estar preparado para recibirla. Para ello tenemos que indicarle al SO el nombre de la rutina del proceso que ha de tratar ese tipo de senal. Si un proceso recibe una senal sin estar preparado para ello, se suele matar al proceso.
Podemos utilizar las senales como el mecanismo mas sencillo de pasar informacion entre procesos, esto es extremadamente rudimentario, pero se puede usar. Asi, podriamos usar \textit{kill -2 pid} donde pid es el pid de un proceso que esta actualmente activo, y -2 tiene el mismo comportamiento que el control-c. \par
Manejadores de senales: podemos usar la funcion signal para capturar una determinada senal y cambiar el comportamiento que tiene por defecto. Esto se hace con la funcion \textit{signal} \par
Para poder mandar senales a algun proceso tenemos que ser los que lo creamos.
\subsection{Servicios de procesos}
Gestion de procesos:
\begin{itemize}
\item{Identificador de proceso: PID (pid\_t)}
\item{Obtener el identificador de proceso: getpid() devuelve el identificador del proceso que hizo la llamada}
\item{Obtener el identificador del proceso padre: getppid()}
\item{Obtener el identificador de usuario real: getuid()}
\item{Obtener el identificador de usuario efectivo: geteuid()}
\item{Obtener el identificador de grupo real: getgid()}
\item{Obtener el identificador de grupo efectivo: getegid()}
\item{Obtener el valor de una variable de entorno: *getenv( const char * name )}
\item{Fijar el entorno de proceso: *setenv(char **env)}
\item{Crear un proceso: fork(). Clona al proceso que lo creo, pasando a ser su hijo}
\item{Ejecutar un programa: familia exec. Cambia el programa que esta ejecutando un proceso}
\item{Terminar la ejecucion de un proceso: exit(int status). Similar a los return}
\item{Esperar a la finalizacion de un proceso hijo: wait(int *status) o wait\_pid(pid\_t , int * status, int options)}
\item{Suspender la ejecucion de un proceso: sleep(unsigned int seconds)}
\end{itemize}
Gestion de threads:
\begin{itemize}
\item Atributos de un thread: (cada thread tiene asociado unos atributos, y los valores de estos se almacenan en un objeto de tipo \textit{pthread\_attr\_t}
\begin{itemize}
\item Crear atributos de un thread: int pthread\_attr\_init(pthread\_attr\_t *attr);
\item Destruir atributos: int pthread\_attr\_destroy(pthread\_attr\_t *attr);
\item Asignar tamano al thread: int pthread\_attr\_setstacksize(pthread\_attr\_t *attr);
\item Obtener el tamano de la pila: int pthread\_attr\_getstacksize(pthread\_attr\_t *attr)
\item Establecer el estado de terminacion: int pthread\_attr\_setdetachstate(pthread\_attr\_t * attr, int detachstate). El valor del segundo argumento, indicara la independencia o no del thread con respecto a otros.
\item Obtener el estado de terminacion: int pthread\_attr\_setdetacstate(pthread\_attr\_t * attr, int * detachstate)
\end{itemize}
\item Creacion, identificaciony terminacion de threads:
\begin{itemize}
\item Crear un thread: int pthread\_create(pthread\_t *thread, pthread\_attr\_r *attr, void * (*start\_routine) (void *), void * arg). El primer argumento es el indentificador, el segundo atributos de ejecucion, el tercero el nombre de la funcion a ejecutar cuando se lance y el ultimo es un puntero a void.
\item Obtener el identificador de un thread: pthread\_t pthread\_self(void)
\item Esperar la terminacion de un thread: int pthread\_join(pthread thid, void **value). Es necesario indicar el thread por el que se quiere esperar.
\item Finalizar la ejecucion de un thread: int pthread\_exit(void * value)
\end{itemize}
\end{itemize}
\end{document}