Lab05 SO
Lab05 SO
INFORME DE LABORATORIO
INFORMACIÓN BÁSICA
ASIGNATURA: Laboratorio de Sistemas Operativos - C
TÍTULO DE LA
Programación de colas de mensajes
PRÁCTICA:
NÚMERO DE NRO.
05 AÑO LECTIVO: 2023 VI
PRÁCTICA: SEMESTRE:
FECHA DE HORA DE
09/10/2023
PRESENTACIÓN PRESENTACION
ALUMNO:
Llaique Chullunquia Angie Carolina NOTA:
DOCENTE(s):
Apaza Aceituno Roni Guillermo
SOLUCIÓN Y RESULTADOS
I. EJERCICIOS RESUELTOS POR EL DOCENTE
Ejercicio 1.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo crea.c, compilelo:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct Msm {
long mtype;
int litros;
}Msm;
void enviarDatos(int msgid, long tipo){
struct Msm msm;
msm.mtype=tipo;
int i;
for (i = 0; i < 10; ++i) {
msm.litros = 10000*i;
msgsnd(msgid,&msm,sizeof(Msm)-sizeof(long),IPC_NOWAIT);
}
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
//
char buffer[12];
scanf("%s",buffer);
//liberar
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ gcc -w crear.c -o crear
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 2.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo leer.c, compilelo:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>
struct Msm {
long mtype;
int litros;
}Msm;
void leerDatos(int msgid,long tipo){
struct Msm msm;
int i;
for (i = 0; i < 10; ++i) {
msgrcv(msgid,&msm,sizeof(msm)-sizeof(long),tipo,0);
printf("tipo mensaje: [%ld] litros: [%d]\n",msm.mtype,msm.litros);
}
}
int main(int argc, const char *argv[])
{
//crear
key_t clave = ftok("/temp",40);
int msgid = msgget(clave,0660);
if(msgid<0){
perror("error en cola\n");exit(1);}
//envia datos
leerDatos(msgid, 2);
leerDatos(msgid, 1);
return 0;
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 3.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo writer.c, compílelo
// Programa en C para la cola de mensajes (proceso que escribe)
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX 10
// Estructura para la cola de mensajes
struct mesg_buffer {
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t key;
int msgid;
Ejercicio 4.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo reader.c,
compílelo
// Programa en para la cola de mensajes (proceso lector)
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main()
{
key_t key;
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
int msgid;
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ gcc reader.c -o reader
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 5.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo masgq_send.c,
compílelo
/* Nombre de archivo: msgq_send.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 6.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo masgq_recv.c,
compílelo
/* Nombre de archivo: msgq_recv.c */
#include <stdio.h>
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define PERMS 0644
struct my_msgbuf {
long mtype;
char mtext[200];
};
int main(void) {
struct my_msgbuf buf;
int msqid;
int toend;
key_t key;
Ejercicio 7
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo elqueenvia.c,
compílelo
#include <stdio.h>
#include <stdlib.h>
#include <linux/ipc.h>
#include <linux/msg.h>
/* Redefiniendo la estructura msgbuf */
typedef struct mymsgbuf
{
long mtype;
int int_num;
float float_num;
char ch;
} mess_t;
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
int main()
{
int qid;
key_t msgkey;
mess_t sent;
mess_t received;
int length;
/* Inicialice la semilla del generador del numero pseudo random */
srand (time (0));
/* Longitud el mensaje */
length = sizeof(mess_t) - sizeof(long);
msgkey = ftok(".",'m');
/* Crea la cola */
qid = msgget(msgkey, IPC_CREAT | 0660);
printf("QID = %d\n", qid);
/* Construye el mensaje */
sent.mtype = 1;
sent.int_num = rand();
sent.float_num = (float)(rand())/3;
sent.ch = 'f';
/* Envia el mensaje */
msgsnd(qid, &sent, length, 0);
printf("MENSAJE ENVIADO...\n");
/* Recibe el mensaje */
msgrcv(qid, &received, length, sent.mtype, 0);
printf("MENSAJE RECIBIDO...\n");
/* Controla que lo que se ha recibido sea igual a lo que se ha enviado */
printf("Numero entero = %d (sent %d) -- ", received.int_num,
sent.int_num);
if(received.int_num == sent.int_num) printf(" OK\n");
else printf("ERROR\n");
printf("Numero flotante = %f (sent %f) -- ", received.float_num,
sent.float_num);
if(received.float_num == sent.float_num) printf(" OK\n");
else printf("ERROR\n");
printf("Char = %c (sent %c) -- ", received.ch, sent.ch);
if(received.ch == sent.ch) printf(" OK\n");
else printf("ERROR\n");
/* Estruye la cola */
msgctl(qid, IPC_RMID, 0);
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ gcc elqueenvia.c -o elqueenvia
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 8.
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo elquerecibe.c,
compílelo
#include <stdio.h>
#include <stdlib.h>
#include <linux/ipc.h>
#include <linux/msg.h>
#include <sys/types.h>
/* Redefine la estructura del mensaje */
typedef struct mymsgbuf
{
long mtype;
int num;
} mess_t;
int main()
{
int qid;
key_t msgkey;
pid_t pid;
mess_t buf;
int length;
int cont;
length = sizeof(mess_t) - sizeof(long);
msgkey = ftok(".",'m');
qid = msgget(msgkey, IPC_CREAT | 0660);
if(!(pid = fork())){
printf("HIJO - QID = %d\n", qid);
srand (time (0));
for(cont = 0; cont < 10; cont++){
sleep (rand()%4);
buf.mtype = 1;
buf.num = rand()%100;
msgsnd(qid, &buf, length, 0);
printf("HIJO – NUMERO DE MENSAJE %d: %d\n", cont+1, buf.num);
}
return 0;
}
printf("PADRE - QID = %d\n", qid);
for(cont = 0; cont < 10; cont++){
sleep (rand()%4);
msgrcv(qid, &buf, length, 1, 0);
printf("PADRE – NUMERO DE MENSAJE %d: %d\n", cont+1, buf.num);
}
msgctl(qid, IPC_RMID, 0);
return 0;
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ gcc elquerecibe.c -o elquerecibe
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 9
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo message_send.c,
compílelo
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#define MSGSZ 128
/*
* Declara la estructura del mensaje.
*/
typedef struct msgbuf {
long mtype;
char mtext[MSGSZ];
} message_buf;
main()
{
int msqid;
int msgflg = IPC_CREAT | 0666;
key_t key;
message_buf sbuf;
size_t buf_length;
/*
* Consigue el id de la cola de mensaje para el
* "name" 1234, el cual ha sido creado
* por el servidor.
*/
key = 1234;
(void) fprintf(stderr, "\nmsgget: llamando a msgget(%#lx,\
%#o)\n",
key, msgflg);
if ((msqid = msgget(key, msgflg )) < 0) {
perror("msgget");
exit(1);
}
else
(void) fprintf(stderr,"msgget: msgget exitoso: msqid = %d\n", msqid);
/*
* We'll send message type 1
*/
sbuf.mtype = 1;
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
buf_length = strlen(sbuf.mtext) + 1 ;
/*
* Enviando mensaje.
*/
if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0) {
printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
perror("msgsnd");
exit(1);
}
else
printf("Message: \"%s\" Sent\n", sbuf.mtext);
exit(0);
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ gcc message_send.c -o message_send
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 10
Crear el siguiente programa en c, que hace referencia a un programa que escribe, llamelo message_rec.c,
compílelo
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#define MSGSZ 128
/*
* Declara la estructura del mensaje.
*/
typedef struct msgbuf {
long mtype;
char mtext[MSGSZ];
} message_buf;
main()
{
int msqid;
key_t key;
message_buf rbuf;
/*
* Consigue el id de la cola de mensje para el
* "name" 1234, el cual ha sido creado por
* el servidor.
*/
key = 1234;
if ((msqid = msgget(key, 0666)) < 0) {
perror("msgget");
exit(1);
}
/*
* Recibe una respuesta del mensaje de tipo 1.
*/
if (msgrcv(msqid, &rbuf, MSGSZ, 1, 0) < 0) {
perror("msgrcv");
exit(1);
}
/*
* Imprime la respuesta.
*/
printf("%s\n", rbuf.mtext);
exit(0);
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 1. Reescriba el programa del ejercicio resuelto 3 para que se pueda validar el ingreso de
números enteros
- Se introdujo una validación para asegurarse de que la entrada sea un número entero válido antes de
continuar.
- Si la entrada es un número entero válido, se convierte a una cadena antes de ser enviada a la cola
de mensajes.
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#define MAX 10
int main() {
key_t key;
int msgid;
message.mesg_type = 1;
char input[MAX];
return 0;
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejecución
Ejercicio 2. Utilizando una tubería simple, redireccione la salida del ejercicio resuelto 2 a un archivo de
texto simple
Para redirigir la salida del ejercicio resuelto 2 de nombre ‘leer.c’a un archivo de texto utilizando una
tubería simple |, se ejecuta el programa del ejercicio resuelto 2 y, al mismo tiempo, redirigir su salida
estándar a un archivo utilizando un comando como cat
En este caso, el programa "leer" se ejecuta y su salida estándar se envía a través de una tubería al
comando cat, que a su vez redirige la salida a un archivo llamado "salida.txt". La tubería | se utiliza para
conectar la salida del programa al comando cat. El resultado es que la salida generada por el programa se
almacena en el archivo "salida.txt".
Primero debemos ejecutar el ejercicio resuelto 1 (crear.c). Luego recién podemos ejecutar leer.c y
redireccionar la salida:
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 3. En el ejercicio resuelto 5 reacomode el tamaño del buffer para mensajes de cadenas de
longitud de 8 caracteres
Modificamos la longitud del campo mtext de la estructura my_msgbuf para que tenga 8 caracteres en lugar
de 200. No necesitaría modificaciones significativas para que el campo mtext de la estructura my_msgbuf
tenga una longitud máxima de 8 caracteres. Dado que el programa ya utiliza fgets para leer líneas de texto,
este enfoque funcionará de manera adecuada sin cambios adicionales.
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejecución
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
La biblioteca sys/ipc.h se utiliza en los ejercicios resueltos para trabajar con las funciones y estructuras
relacionadas con la gestión de claves y control de colas de mensajes en el contexto de la programación en C.
Definir estructuras de datos que son necesarias para operaciones IPC, como la estructura struct ipc_perm
que almacena información de permisos.
Definir funciones para la creación y gestión de colas de mensajes, semáforos y segmentos de memoria
compartida, como msgget, semget, shmget, y funciones relacionadas.
Definir constantes y macros que son necesarias para configurar permisos y opciones en las llamadas a las
funciones IPC.
Si se está compilando un programa y se produce un error que indica que no se encuentra el archivo
sys/types.h, es posible que falte instalar el paquete de encabezados de desarrollo correspondiente. En ese
caso, se puede instalar el paquete libc6-dev
REFERENCIAS Y BIBLIOGRAFÍA
[1] Giordani Leonardo. 2013 07 21 Programación Concurrente - Colas de mensajes : online, Available:
http://www.linuxfocus.org/Castellano/March2003/article287.shtml
[2]The Open Group Publications Catalog. Accedido el 13 de octubre de 2023. [En línea]. Disponible:
https://pubs.opengroup.org/onlinepubs/7908799/xsh/sysipc.h.html
[3]“Where is sys/types.h located?” Stack Overflow. Accedido el 13 de octubre de 2023. [En línea]. Disponible:
https://stackoverflow.com/questions/11823063/where-is-sys-types-h-located