Cuestionario 2

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 11

Benemérita Universidad Autónoma de Puebla

Cuestionario 2
Sistemas Operativos 1

Fabio Julián Ibarra Suárez


18 de Abril de 2020
1. ¿Qué información comparten un proceso y su hijo después de ejecutar el siguiente
código?
if (fork()!=0)
wait (&status);
else
execve (B, parámetros, 0);

Datos, pila, descriptores de archivos abiertos.

2. En un sistema operativo conforme a la norma POSIX,Cuando pasa un proceso al estado de zombie?

Proceso parado que queda en la tabla de procesos hasta que termine su padre, esto ocurre cuando el
proceso padre no recoge el código de salida del proceso hijo.

3. Tras la ejecución del siguiente código, ¿Cuantos procesos se habrán creado?

For(i=0;i<n;i++)
fork();

Se crea (2*n-1)

4. Cuando un proceso ejecuta una llamada fork y luego el proceso hijo un exec, que informacion
comparten ambos procesos?

La función exec() esta función cambia la imagen del proceso actual, lo que realiza es sustituir la
imagen de memoria del programa por la de un programa diferente. Esta función normalmente la
invocaremos en un proceso hijo previamente generado por fork().

5. Que diferencia existe entre bloquear una senal e ignorarla en POSIX?

Decidir entre atrapar la señal (asignar un manejador para la señal => función especial que se ejecuta
cuando es depositada) o bien ignorar la señal.
Establecer el bloqueo de la señal (la señal queda pendiente de ser depositada) Es un aspecto de
configuración independiente para cada thread.

6. Escribir un programa en C que active unos manejadores para las senales SIGINT,SIGQUIT y
SIGILL. Las acciones a ejecutar por dichos manejadores seran:

a.Para SIGINT y SIGQUIT, abortar el proceso con un estado de error .

b.Para SIGILL,imprimir un mensaje de instrucción ilegal y terminar .


#include <stdio.h>
#include <signal.h>

void abortar_proceso(){
exit(-1);
}
void msg_terminar(){
printf(“Instruccion ilegal\n”);
exit(-1);
}
main(){
struct sigaction act;
sigset_s mask;
act.sa_handler = abortar_proceso;
sigemptyset(&act.mask);
sigaction(SIGINT,&act,NULL);
sigaction(SIGINT,&act,NULL);
act.sa_handler = msg_terminar;
sigemptyset(&act.mask);
sigaction(SIGQUIT,&act,NULL);
}

7.Dado el siguiente programa en c

void main(int argc,char argv){


int i;
for(i=1;i<=argc,i++)
fork();

Realizar :
a.Dibujar un esquema que encuentre la jerarquia de procesos que se crea cuando se ejecuta el
programa con argc igual a 3.
Proceso1
Proceso1Proceso2(i=1)
Proceso1Proceso3Proceso2Proceso4(i=2)

Proc1Proc5Proc3Proc6Proc7Proc8(i=3

b.Cuantos procesos se crean sin argc vale n?


Se crean (2**n-1)procesos nuevos,Proceso1

8.Explica la diferencia entre semáforos, memoria compartida y cola de mensajes para la comunicación
entre procesos.

Una cola de mensajes es una estructura de datos gestionada por el kernel, en la cual van a poder escribir
y leer los procesos que se ejecuten en el sistema. Los mecanismos de sincronismo para que no se
produzcan colisión son responsabilidad del kernel.
Un semáforo es una variable especial(o tipo abstracto de datos) que construyen el método clásico para
restringir o permitir el acceso a recursos compartidos(por ejemplo, un recurso de almacenamiento del
sistema o variables del código fuente) en un entorno de multiprocesamiento (en el que se ejecutaran
varios procesos concurrentemente).

La memoria compartida es aquel tipo de memoria que puede ser accedida por múltiples programas, ya
sea para comunicarse entre ellos o para evitar copias redundantes. La memoria compartida es un n
modo eficaz de pasar datos entre aplicaciones.

9. La siguiente es una lista con algunas de las llamadas al sistema que se deben conocer para entender
la sincronización entre procesos en el sistema y el mecanismo de memoria compartida identifica y
describe que llamada realizan al sistema.

Fork : Esta es una llamda a sistema para el control de procesos que al ser invocada genera un
proceso hijo, como una copia del proceso en donde fue invocada la llamda, este hijo es casi
exactamente igual a su padre(lo unico que los diferencia es su pid xd=fork();

wait:Al ser iinvocada, suspende el proceso que la invoco para que su proceso hijo termine de
ejecutar su codigo(es decir, espera a su hijo) o hasta el proceso invocador reciba una senal de
terminacion de proceso.
Para poder ser invocada deben incluirse los archivos de cabecera:
sys/types.h
sys/wait.h
pid_t wait(int *status)

waitpid: wait tiene una llamada prima hermana denominada waitpid. Su prototipo es: pid_t
waitpid(pid_t pid, int *stat_loc, int options);

exit:Su funcionamiento es análogo a la instrucción return x;, es decir, finaliza el


proceso que la invoca y retorna al proceso padre el valor colocado como argumento (si es
cero indica que se terminó normalmente, en caso contrario indica que se produjo un error).
No retorna ningún valor al proceso que la invoca y debe incluirse el archivo de cabecera:
stdlib.h para poderse usar.

Shmctl:Es exactamente paralela a msgctl.


int shmctl(int shmid, int command, struct shmid_ds *shm_stat);
Los valores que puede usar command son IPC_STAT, IPC_SET y IPC_RMID.

Shmget:Esta llamada es similar a semget y msgget.


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
.
int shmget(key_t llave, int tamaño, int permisos);
Donde :
tamaño es el mínimo tamaño requerido del segmento de memoria (en bytes).
llave es la llave que identifica el segmento de memoria,
y el tercer argumento son los permisos, que pueden ser manejados como en msgget
(IPC_EXCL, IPC_CREAT).

Shmat:Ata el segmento de memoria al espacio de datos lógico del proceso.


char *shmat (int shmid, char *daddr, int permisos);
asocia el segmento de memoria asociado con shmid con una dirección válida para el proceso
invocador, el cual es retornado por shmat

shmdt:Es la operación inversa a shmat.


int shmdt(char *memptr);
Devuelve 0 en caso de éxito y –1 en caso de error.

Semget:Crea un grupo de semáforos e inicia cada elemento a 0.


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
Donde:
key identifica al grupo de semáforos,
nsems es el número de semáforos en el arreglo y
semflg son las banderas.

Semctl:Conjunta o agrupa los valores de elementos individuales de semáforo. También


ejecuta otras funciones de control, incluyendo la destrucción del semáforo.
int semctl(int semid, int semnum, int cmd, /*union semun arg */ ...);

semop:Función mediante la cual un proceso puede incrementar, reducir o probar en


forma individual los elementos de un semáforo para determinar un valor cero.
int semop ( int semid, struct sembuf *sops, int nsops );

sleep:permite suspender (bloquear) la ejecución actual por un intervalo de tiempo


determinado.

10.Se enumeran algunos de los comandos explica su funcionamiento

gcc Es un compilador para GNU considerado estándar para los Sistemas Operativos
derivados de UNIX, de Código abierto Las siglas GCC significan GNU Compiler Collection
(Colección de compiladores GNU)..

make Es muy usada en los sistemas operativos tipo Unix/Linux. Por defecto lee las
instrucciones para generar el programa u otra acción del fichero makefile. Las instrucciones
escritas en este fichero se llaman dependencias.
man es una herramienta de sistemas Unix que se utiliza para documentar y aprender
sobre comandos, archivos, llamadas de sistema, etc., en un sistema operativo tal como
GNU/Linux.
$ man [comando]

ps Es una funcion que te permite visualizar el estado de un proceso.

kill:Es un comando utilizado para enviar mensajes sencillos a los procesos ejecutándose en
el sistema.
gdb:Es el depurador estándar para el compilador GNU. ofrece la posibilidad de trazar y
modificar la ejecución de un programa. El usuario puede controlar y alterar los valores de las
variables internas del programa. no contiene su propia interfaz grafica de usuarios y por
defecto se controla mediante una interfaz de linea de comandos. Existen diversos front-ends
que han sido diseñados para GDB, como Data DisplayDebugger, GDBtk\Insight y el «modo
GUD» en Emacs.
ipcs: Es una función básica de los Sistemas operativos. Los procesos pueden comunicarse
entre sí a través de compartir espacios de memoria, ya sean variables compartidas o buffers,
o a través de las herramientas provistas por las rutinas de IPC.
Semáforos, memoria compartida, tuberías, colas de mensajes
ipcrm: para eliminar un semáforo

11.Revisar codigo y contestar preguntas

a)Cual es la salida del siguiente programa y explica como lo realiza?

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

static void charatatime(chat*);


int main(void){
pid_t pid;
if(pid = fork())<0){

perror(“fork error”);
exit(1);
}
else if( pid == 0){
charatatime("Salida desde el hijo\n");
}
else{
charatatime("Salida desde el padre\n");
}
exit(0);
}
static void charatatime(char * str) {
char * ptr;
int c;

setbuf(stdout,NULL);
for( (ptr = str); (c = *ptr++); ){
//sleep(1);
putc(c, stdout);
}
}

b) ¿Cuál es la salida del siguiente programa y explica cómo lo realiza?


#include <stdio.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/wait.h>

int main(void) {
pid_t pid;
int status;

pid = fork();

if(pid < 0){


fprintf(stderr, "Fallo :( \n");
exit(‐1);
}
else {
if (pid == 0){
printf("HIJO: Me duermo por 10 seg y luego hago un 'ls'\n");
sleep(10);
execlp("/bin/ls", "ls", NULL);
}
else{
printf("PADRE: Estoy esperando a mi hijo ...\n");
waitpid(pid,&status,WUNTRACED);
printf("PADRE: El hijo termino: status=%d \n", status);
exit(0);
}

}
exit(0);
}

Primero crea un proceso hijo utilizando la llamada de una funcion(); el hijo llama a la funcion
charatatime(), donde le envia una cadena de caracteres, y esta funcion usando putc(c,sdout) manda a
stdout el mensaje carácter a carácter.
EJERCICIOS

12. Crea un programa que haga que un hijo haga una suma de números pasados por parámetro
para que después, cuando el hijo muera, devuelva al programa padre la suma de dichos números

int sum = 0;
pid_t child;
child = fork();
if (child == -1) {
printf("ERROR");
return -1;
} else if (child == 0) {
int sum;
for (int i = 1; i < argc; i++) {
sum = atoi(argv[i]) + sum;
}
} else {
wait(&status);
printf("SUMA: %d", sum); }
return 0; }

13. Crea un programa en el cual un padre crea un hijo. El padre imprimirá por pantalla la palabra
hijo cada 10 segundos. El hijo matara al padre a los 25 segundos.

int main(void)
{
pid_t pid;
int x;

pid = fork();
if (pid){
/* padre */
printf("Inicio proceso PADRE %d \n",getpid());

}
else
{ /* hijo */

printf("Soy el hijo %d \n",getpid());


exit(0);
}

for (x=0; x<=5; x++)


{
printf("Proceso PADRE\n HIJO \n",x,getpid());
sleep(10);
}
sleep(25);
printf ("EL PADRE %d excedio el tiempo y tiene que morir",pid);
kill(pid,SIGKILL);
return 0;

14. Programa que envía mensajes entre un proceso emisor y otro receptor a través de dos tuberías
sin nombre, lo que permite implementar una comunicación bidireccional. El proceso emisor pedirá
un mensaje que le enviara al proceso receptor. Cuando el proceso receptor haya presentado el
mensaje por pantalla, solicitara al proceso emisor otro mensaje, indicándole así que está listo y
que puede pedirle otro mensaje al usuario.

#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define MAX 256

void limpia(char *cadena) {//limpia buffer de entrada cada vez que recibe el mensaje
char *p = strchr(cadena, '\n');
if (p) {
*p = '\0';
}
}

int main(int argc, char *argv[]) {


int tuberia_P[2];//Principal Secundaria
int tuberia_S[2];//necesitamos una tuberÃa que sirva de canal entre el proceso
receptor y el emisor.
int pid;
char mensaje[MAX];

if (pipe(tuberia_P) < 0 || pipe(tuberia_S) < 0) {//se valida la creacion de la tuberia


perror("pipe");
return -1;
}

if ((pid = fork()) < 0) {


perror("fork");
return -1;
} else if (pid == 0) {
while(read(tuberia_P[0], mensaje, MAX) > 0 && strcmp(mensaje, "Adios") != 0)
{//si la cadenas es igual a eso termina
fprintf(stdout, "Mensaje Receptor: %s\n", mensaje);
strcpy(mensaje, "LISTO");
//Mandamos el mensaje de listo a travez de la tuberia secundaria para
hacer la siguiente comunicacion
//correctamente
write(tuberia_S[1], mensaje, strlen(mensaje) + 1);
printf("Listo para recibir\n");
}
close (tuberia_P[0]);
close (tuberia_P[1]);//Cerramos el canal de comunicacion del pipe de escritura y
de lectura de ambas tuberias
close (tuberia_S[0]);
close (tuberia_S[1]);
return 0;
} else {
do {
fprintf(stdout, "Mensaje Emisor: ");
fgets(mensaje, MAX, stdin);
limpia(mensaje);
write(tuberia_P[1], mensaje, strlen(mensaje) + 1);
if (strcmp(mensaje, "Adios") == 0) {
break;
}
do {
strcpy(mensaje, "");
read(tuberia_S[0], mensaje, MAX);
} while (strcmp(mensaje, "LISTO") != 0);//la tuberia del receptor se
compara para que pueda continuar
} while (1);
close (tuberia_P[0]);
close (tuberia_P[1]);
close (tuberia_S[0]);
close (tuberia_S[1]);
return 0;
}
}

También podría gustarte