Documentos de Académico
Documentos de Profesional
Documentos de Cultura
INFORME DE LABORATORIO
INFORMACIÓN BÁSICA
ASIGNATURA: Laboratorio de Sistemas Operativos - C
TÍTULO DE LA
Threads en C - PTHREADS
PRÁCTICA:
NÚMERO DE NRO.
06 AÑO LECTIVO: 2023 VI
PRÁCTICA: SEMESTRE:
FECHA DE HORA DE
18/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 un simple thread usando la librería pthread:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //cabecera para usar sleep().
#include <pthread.h>
// Una función normal de c que es ejecutadad en un thread
// cuando es nombrada, es especificada como pthread_create()
void *myThreadFun(void *vargp)
{
sleep(1);
printf("Imprimiendo ejemplo Thread \n");
return NULL;
}
int main()
{
pthread_t thread_id;
printf("Antes del Thread\n");
pthread_create(&thread_id, NULL, myThreadFun, NULL);
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
pthread_join(thread_id, NULL);
printf("Despues del Thread\n");
exit(0);
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ gcc -w ejercicio01.c -lpthread -o ejercicio01
Ejercicio 2.
Escribir el siguiente thread, después compílelo y ejecutelo:
// Importando la librería Pthread
#include <pthread.h>
// Importando la librería para usar printf
#include <stdio.h>
// Esta función tomo en un puntero
void * ThreadFunction(void *arguments)
{
printf("Thread Running\n");
return NULL;
}
int main() {
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
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
main()
{
pthread_t thread1, thread2;
char *message1 = "Thread 1";
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 4.
Crear el siguiente programa en c, que creará tres hilos usando un bucle for, compílelo
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
// Permite crear una variable global para cambiarlo in los threads
int g = 0;
// La función será ejecutada por todos los threads
void *myThreadFun(void *vargp)
{
// Aloja el valor del argumento pasado por el thread
int *myid = (int *)vargp;
// Permite crear una variable estatic para observar los cambios
static int s = 0;
// Cambia la variable global y estatica
++s; ++g;
// Imprime los argumentos de las variables global y estaticas
printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g);
}
int main()
{
int i;
pthread_t tid;
// Nos permtie crear tres threads
for (i = 0; i < 3; i++)
pthread_create(&tid, NULL, myThreadFun, (void *)&tid);
pthread_exit(NULL);
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ gcc ejercicio04.c -lpthread -o ejercicio04
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, compílelo con el nombre ejercicio05.c
# include < stdio.h >
# include < stdlib.h >
# include < string.h >
# include < unistd.h >
# include < pthread.h >
void * slowprintf ( void * arg ) {
char * msg ;
int i;
msg = ( char *) arg ;
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 el paso de parámetros usando una estructura, llamelo ejercicio06.c,
compílelo
# include < stdio .h >
# include < stdlib .h >
# include < string .h >
# include < unistd .h >
# include < pthread .h >
struct parametros {
int id ;
float escalar ;
float matriz [3][3];
};
void init ( float m [3][3]) {
int i;
int j;
for ( i = 0 ; i < 3 ; i ++ ) {
for ( j = 0 ; j < 3 ; j ++ ) {
m[i ][ j ] = random () *100;
}
}
}
void * matrizporescalar ( void * arg ) {
struct parametros * p;
int i;
int j
p = ( struct parametros *) arg ;
for ( i = 0 ; i < 3 ; i ++ ) {
printf (" Hilo %d multiplicando fila %d \n" , p -> id , i );
for ( j = 0 ; j < 3 ; j ++ ) {
p -> matriz [ i ][ j] = p -> matriz [ i ][ j] * p -> escalar ;
usleep (100000) ;
}
}
}
int main ( int argc , char * argv []) {
pthread_t h1 ;
pthread_t h2 ;
struct parametros p1 ;
struct parametros p2 ;
p1 . id = 1;
p1 . escalar = 5.0;
init ( p1 . matriz );
p2 . id = 2;
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
p2 . escalar = 10.0;
init ( p2 . matriz );
pthread_create (& h1 , NULL , matrizporescalar , ( void *) & p1);
pthread_create (& h2 , NULL , matrizporescalar , ( void *) & p2);
pthread_join ( h1 , NULL ) ;
pthread_join ( h2 , NULL ) ;
printf ( " Fin \n ");
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ gcc ejercicio06.c -lpthread -o ejercicio06
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 7
Crear el siguiente programa en c, que cancela la ejecución de un thread usando la función cancel(), llamelo
ejercicio07.c, compílelo
// Un programa en C para demostrar la cancelación de un thread propio
// usando el id del thread
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* calls(void* ptr)
{
printf("Cancelado");
// Para salir del actual thread
// pthread_self() devuelve el valor del id del thread
pthread_cancel(pthread_self());
return NULL;
}
int main()
{
// NULL cuando no hay atributo
pthread_t thread;
// Llamada a funciíon
pthread_create(&thread, NULL, calls, NULL);
// Esperando cuando el thread es completado
pthread_join(thread, NULL);
return 0;
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ gcc ejercicio07.c -lpthread -o ejercicio07
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 cancela varios threads, llamelo ejercicio08.c, compílelo
// Programa en C para demostrar la cancelación de los threads
// usando el id del thread
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
// To Count
int counter = 0;
// temporalmente el thread será
// almacenando el id del segundo thread
pthread_t tmp_thread;
// thread_uno llama a func
void* func(void* p)
{
while (1) {
printf("thread numero uno\n");
sleep(1); // duerme por 1 segundo
counter++;
// para salir si el contadore es 5
if (counter == 2) {
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 compara dos threads, llamelo ejercicio09.c, compílelo
// Programa en C para demostrar como trabaja pthread_equal()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
pthread_t tmp_thread;
{
// en este camplo comparamos los threads
// pthread_self da un id del thread actual
if (pthread_equal(tmp_thread, pthread_self())) {
printf("son iguals\n");
} else {
printf("no son iguales\n");
}
}
// driver code
int main()
{
// thread uno
pthread_t thread_one;
// creando el thread
pthread_create(&thread_one, NULL, func_one, NULL);
Ejercicio 10
Crear el siguiente programa en c, que compara dos threads, llamelo ejercicio10.c, compílelo
// Programa en C para demostrar como trabaja pthread_equal()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
// la variable global pthread_t es declarada
pthread_t tmp_thread;
void* func_one(void* ptr)
{
tmp_thread = pthread_self(); // assign the id of thread one in
// temporalmente el thread declara la variable global
}
void* func_two(void* ptr)
{
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
El programa divide el trabajo en múltiples threads, cada uno suma una porción del arreglo y
luego se acumulan los resultados en la variable suma_total. El resultado final se imprime
correctamente al final del programa.
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 4
#define ARRAY_SIZE 100
int main() {
pthread_t threads[NUM_THREADS];
int ids_threads[NUM_THREADS];
// Inicializar el arreglo
for (int i = 0; i < ARRAY_SIZE; i++) {
mi_arreglo[i] = i;
}
// Crear threads
for (int i = 0; i < NUM_THREADS; i++) {
ids_threads[i] = i;
pthread_create(&threads[i], NULL, sumar_segmento, &ids_threads[i]);
}
// Esperar a que todos los threads terminen
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// Imprimir el resultado
printf("Suma total: %d\n", suma_total);
return 0;
}
Código
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
Para crear hilos, se puede utilizar la biblioteca pthread.h, que proporciona funciones para la
creación y gestión de hilos. Por otro lado, para crear procesos, se puede utilizar la función
fork(), que crea un proceso hijo idéntico al proceso padre. Cada proceso tiene su propio
espacio de memoria y no comparte recursos con otros procesos, lo que puede ser útil para
evitar problemas de concurrencia. La elección entre hilos y procesos depende del problema
que se esté tratando y de los recursos disponibles. Si se necesita compartir información entre
los hilos, puede ser más conveniente utilizar hilos, mientras que si se necesita aislar los
procesos para evitar problemas de concurrencia, puede ser más conveniente utilizar procesos.
Observamos que los hilos comparten el mismo espacio de memoria y recursos, mientras que
los procesos tienen su propio espacio de memoria y recursos. La creación de hilos suele ser
más eficiente en términos de recursos que la creación de procesos debido a esta compartición
de recursos.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pthread_t hilos[NUM_THREADS];
pid_t procesos[NUM_PROCESSES];
return 0;
}
Código
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
Es importante tener en cuenta que la creación de procesos implica más sobrecarga debido a la
duplicación del espacio de memoria del proceso padre, mientras que los hilos comparten la
misma memoria del proceso padre. La elección entre hilos y procesos depende de los
requisitos y limitaciones de tu aplicación.
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Ejercicio 3. Demostrar que el thread creado en una función de un proceso es el mismo que
es usado en la función principal main
Esto se debe a que los threads se crean, ejecutan y mueren dentro de los procesos, y son
capaces de compartir información entre ellos. Además, un thread es la unidad más pequeña a
la cual un procesador puede asignar tiempo. Por lo tanto, el thread creado en una función de
un proceso es parte del mismo proceso que la función principal main y, por lo tanto, es el
mismo thread.
Se imprime el identificador de hilo (pthread_t) tanto en la función main como en la función
thread_function, y se demuestra que estos identificadores son los mismos.
En el contexto de hilos en un programa, los hilos comparten el mismo espacio de memoria del
proceso que los creó. Por lo tanto, el contexto del hilo creado en una función de un proceso es
el mismo que el contexto del proceso principal, incluido el espacio de memoria. Esto significa
que las variables y datos creados en el proceso principal pueden ser accedidos y compartidos
por los hilos que se crean dentro de ese proceso.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main() {
pthread_t thread_id;
printf("Identificador del hilo principal: %ld\n", (long) pthread_self());
pthread_create(&thread_id, NULL, thread_function, NULL);
pthread_join(thread_id, NULL);
return 0;
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
Código
Ejecución
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA
La función pthread_detach() de la librería pthread se utiliza para marcar un hilo como desvinculado[3].
Cuando un hilo desvinculado termina, sus recursos se liberan automáticamente sin necesidad de que otro
hilo se una al hilo terminado[4].
En otras palabras, la función marca el hilo como "desconectado" o "desvinculado" y permite que los
recursos asociados con el hilo se liberen automáticamente cuando el hilo termina, sin necesidad de que
otro hilo se una al hilo terminado.
Donde thread es el identificador del hilo que se desea marcar como desprendido.
En resumen, la función pthread_detach se utiliza para marcar un hilo como "desconectado" y permitir que
los recursos asociados con el hilo se liberen automáticamente cuando el hilo termina. Es importante tener
en cuenta que una vez que un hilo ha sido desconectado, no se puede volver a unir con pthread_join o
hacerlo unible de nuevo. La función se utiliza comúnmente en conjunción con pthread_create para crear
hilos que se ejecutan de forma independiente y no necesitan ser unidos con otros hilos, o para liberar
recursos asociados con hilos que ya no son necesarios.
La función pthread_kill() de la librería pthread se utiliza para enviar una señal a un hilo específico[6]. La
señal se envía de forma asíncrona al hilo especificado. Si el argumento sig es 0, no se envía ninguna señal,
pero se realiza la verificación de errores[7].
Es importante tener en cuenta que pthread_kill() no termina el hilo receptor, sino que envía una señal a él.
El comportamiento del hilo receptor depende de la señal y los manejadores de señales[8].
Por ejemplo, si se envía la señal SIGTERM a un hilo, el hilo puede terminar o puede ser manejado por un
manejador de señales personalizado que realice una acción diferente
En resumen, la función pthread_kill se utiliza para enviar una señal a un hilo específico en el proceso que
llama. La señal enviada puede ser cualquier señal definida en signal.h, excepto la señal 0. Es importante
tener en cuenta que la señal enviada no necesariamente terminará el hilo, y dependerá de la señal y los
manejadores de señales lo que suceda después. La función se utiliza comúnmente en conjunción con
manejadores de señales personalizados para controlar el comportamiento de los hilos en respuesta a
señales específicas, o para enviar señales a hilos específicos para indicarles que realicen una acción
específica.
REFERENCIAS Y BIBLIOGRAFÍA
[1] Z. Stefano. 2015 Programmation Système Cours 9 POSIX Threads an introduction: online, Available:
https://upsilon.cc/~zack/teaching/1415/progsyst/cours-09-pthreads.pdf
[2] D.Fernando. 2017/03/13], Threads POSIX: online, Avalible: https://www.embarcados.com.br/threadsposix/
[3] POSIX Threads - Universidad Técnica Federico Santa María.
http://profesores.elo.utfsm.cl/~agv/elo330/2s08/lectures/POSIX_Threads.html.
[4] pthread_detach - detach a thread - pubs.opengroup.org.
https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_detach.html.
[5] pthread_detach(3) - Linux manual page - man7.org.
https://man7.org/linux/man-pages/man3/pthread_detach.3.html.
[6] Ubuntu Manpage: pthread_kill - send a signal to a thread.
https://manpages.ubuntu.com/manpages/jammy/man3/pthread_kill.3.html.
[7] pthread_kill(3) — manpages-dev — Debian bullseye — Debian Manpages.
https://manpages.debian.org/bullseye/manpages-dev/pthread_kill.3.en.html.
[8] When to use pthread_cancel and not pthread_kill?.
https://stackoverflow.com/questions/3438536/when-to-use-pthread-cancel-and-not-pthread-kill.