Está en la página 1de 22

UNIVERSIDAD NACIONAL DE SAN AGUSTIN

FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS


ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 1

INFORME DE LABORATORIO

INFORMACIÓN BÁSICA
ASIGNATURA: Laboratorio de Sistemas Operativos - C
TÍTULO DE LA
Introducción a Linux
PRÁCTICA:
NÚMERO DE NRO.
09 AÑO LECTIVO: 2023 VI
PRÁCTICA: SEMESTRE:
FECHA DE HORA DE
10/11/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.
Implementar dos threads usando la librería thread de c++, guardar el programa con el nombre de
ejercicio01.cpp:
#include <iostream>
#include <thread>
void foo(){
std::cout<<"estoy en foo\n";
}
void bar(){
std::cout<<"estoy en bar\n";
}
int main(){
std::thread th(foo);
std::thread hr(bar);
th.join();
hr.join();
}
/* Crear una clase con funciones miembro, que sean llamadas por un thread */
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$g++ -W ejercicio01.cpp -o ejercicio01 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 2

Ejercicio 2.
Crear un programa que implemente dos threads y muestre sus IDs, guardar el programa con el nombre de
ejercicio02.cpp:
// Programa en C++ para demostrar el uso de
// std::thread::get_id
#include <chrono>
#include <iostream>
#include <thread>
using namespace std;
// funcion util function para la creacion de thread
void sleepThread()
{
this_thread::sleep_for(chrono::seconds(60)); //1 minuto
}
int main()
{
// creando thread1 y thread2
thread thread1(sleepThread);
thread thread2(sleepThread);
thread::id t1_id = thread1.get_id();
thread::id t2_id = thread2.get_id();
cout << "ID asociado con thread1= "
<< t1_id << endl;
cout << "ID asociado con thread2= "
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 3

<< t2_id << endl;


thread1.join();
thread2.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$g++ -W ejercicio02.cpp -o ejercicio02 -std=c++11 -pthread

Ejercicio 3.
Crear dos threads en un programa en C++ que tengan cada uno una variable estática, guardar el programa
con el nombre de ejercicio03.cpp:
// Programa en C++ para implementar
// Alojamiento local estatico del Thread
#include <iostream>
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 4

#include <thread>
using namespace std;
void thread_func()
{
// variable estatica para thread-local
static thread_local int stls_variable = 0;
// Incrementa la variable
stls_variable += 1;
cout << "Thread ID: " << this_thread::get_id()
<< ", Variable: " << stls_variable
<< endl;
}
int main()
{
thread t1(thread_func);
thread t2(thread_func);

t1.join();
t2.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$g++ -W ejercicio03.cpp -o ejercicio03 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 5

Ejercicio 4.
Crear el siguiente programa en c++, donde se crean 2 threads que incrementan cada uno sus contadores y
que muestren también su ID, guarde este programa con el nombre de ejercicio04.cpp, compilelo.
// Programa C++ para implementar
// el alojamiento para thread_local
#include <iostream>
#include <thread>
using namespace std;
thread_local int counter = 0;
void increment_counter()
{
counter++;
cout << "Thread " << this_thread::get_id()
<< " counter = " << counter << endl;
}
int main()
{
// Crear el primer thread
thread t1(increment_counter);
// Crear el segundo thread
thread t2(increment_counter);
// Esperar por el primer thread para finalizar
t1.join();
// Esperar por el segundo thread para finalizar
t2.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ g++ -W ejercicio04.cpp -o ejercicio04 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 6

Ejercicio 5.
Crear el siguiente programa en c++, donde se muestra el uso de un thread para aplicarlo sobre una clase,
guárdelo como ejercicio05.cpp
// Programa en C++ para demostrar el uso del thread-local
// alojada.
#include <iostream>
#include <thread>
using namespace std;
class Singleton {
public:
static Singleton& getInstance()
{
// Cada thread tendria su propia instancia de
// Singleton
thread_local Singleton instance;
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 7

return instance;
}
void printMessage()
{
cout << "Hola desde el thread "
<< this_thread::get_id() << endl;
}
private:
Singleton() = default;
};
void workerThread()
{
Singleton::getInstance().printMessage();
}
int main()
{
// Crear el primer thread
thread t1(workerThread);
// Crear el segundo thread
thread t2(workerThread);
// Esperar por el primer thread para finalizar
t1.join();
// Esperar para el segundo thread para finalizar
t2.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ g++ -W ejercicio05.cpp -o ejercicio05 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 8

Ejercicio 6.
El siguiente programa muestra como la función detach() puede cumplir la misma caracteristicas de join(),
guarde el programa con el nombre de ejercicio06.cpp, compílelo
#include <iostream>
#include <thread>
void thread_function()
{
std::cout << "funcion Thread\n";
}
int main()
{
std::thread t(&thread_function);
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 9

std::cout << "Thread principal\n";


// t.join();
t.detach();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en línea de comandos
$ g++ -W ejercicio06.cpp -o ejercicio06 -std=c++11 -pthread

Ejercicio 7
El siguiente programa demuestra que no se puede usar detach() y join() al mismo tiempo, guarde el
programa con el nombre de ejercicio07.cpp, compílelo
#include <iostream>
#include <thread>
void thread_function()
{
std::cout << "funcion Thread\n";
}
int main()
{
std::thread t(&thread_function);
std::cout << "Thread principal\n";
t.detach();
t.join(); //error
return 0;
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 10

$ g++ -W ejercicio07.cpp -o ejercicio07 -std=c++11 -pthread

Ejercicio 8.
Crear el siguiente programa en cpp, adiciona un thread, solo si tiene la capacidad de ser adicionado
(joinable), llamelo ejercicio08.cpp, compílelo
#include <iostream>
#include <thread>
void thread_function()
{
std::cout << "funcion Thread\n";
}
int main()
{
std::thread t(&thread_function);
std::cout << "Thread principal\n";
// t.join();
if(t.joinable())
t.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ g++ -W ejercicio08.cpp -o ejercicio08 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 11

Ejercicio 9
Crear el siguiente programa en c++, que pasa parametros usando una referencia, llamelo ejercicio09.cpp,
compílelo
#include <iostream>
#include <thread>
#include <string>
void thread_function(std::string s)
{
std::cout << "función thread ";
std::cout << "El mensaje es = " << s << std::endl;
}
int main()
{
std::string s = "Kathy Perry";
std::thread t(&thread_function, s);
std::cout << "el mensaje del thread principal es = " << s << std::endl;
t.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ g++ -W ejercicio09.cpp -o ejercicio09 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 12

Ejercicio 10
Crear el siguiente programa en c++, que copia el contenido de un thread a otro thread ejercicio10.cpp,
compílelo
#include <iostream>
#include <thread>
void thread_function()
{
std::cout << "thread function\n";
}
int main()
{
std::thread t(&thread_function);
std::cout << "main thread\n";
std::thread t2 = move(t);
t2.join();
return 0;
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ g++ -W ejercicio10.cpp -o ejercicio10 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 13

Ejercicio 11
Crear el siguiente programa en c++, que muestra la cantidad de threads que se pueden ejecutar en una cpu,
llamelo ejercicio11.cpp, compílelo

#include <iostream>
#include <thread>
int main()
{
std::cout << "Numero de threads = "
<< std::thread::hardware_concurrency() << std::endl;
return 0;
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ gcc ejercicio11.c -lpthread -o ejercicio11
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 14

Ejercicio 12
Crear el siguiente programa en c++, que crea un thread recibiendo parametros, llamelo ejercicio12.cpp,
compílelo
#include <iostream>
#include <thread>
using namespace std;
void func(int n, double m){
cout << n << " " << m << endl;
}
int main(){
thread th(func, 1, 5.7);

if(th.joinable()) {
th.join();
}
}
Para compilar este programa utilizamos el siguiente comando en linea de comandos
$ g++ -W ejercicio12.cpp -o ejercicio12 -std=c++11 -pthread
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 15

II. SOLUCIÓN DE EJERCICIOS PROPUESTOS


Ejercicio 1. Modifique el ejercicio 01 y cree 4 threads con solo 2 funciones
Creamos cuatro subprocesos, dos de los cuales llaman a la función foo() y dos llaman a la
función bar(). Luego usamos la función join() para esperar a que finalicen los cuatro
subprocesos antes de salir del programa.

#include <iostream>
#include <thread>

void foo(){
std::cout<<"estoy en foo\n";
}

void bar(){
std::cout<<"estoy en bar\n";
}

int main(){
std::thread th1(foo);
std::thread th2(foo);
std::thread th3(bar);
std::thread th4(bar);
th1.join();
th2.join();
th3.join();
th4.join();
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 16

Ejecución

Ejercicio 2. Modifique el ejercicio 02 para que los threads duerman un minuto


Para modificar el ejercicio 02 para que los threads duerman un minuto, se debe cambiar la
duración del tiempo de espera en la función sleepThread(). Actualmente, la función espera por
un segundo antes de terminar. Para que los threads duerman un minuto, se debe cambiar la
duración del tiempo de espera a 60 segundos. La función sleepThread() quedaría así:

#include <chrono>
#include <iostream>
#include <thread>
using namespace std;

void sleepThread() {
this_thread::sleep_for(chrono::seconds(60)); // 1 minuto
}

int main() {
// Creando thread1 y thread2
thread thread1(sleepThread);
thread thread2(sleepThread);
thread::id t1_id = thread1.get_id();
thread::id t2_id = thread2.get_id();
cout << "ID asociado con thread1= " << t1_id << endl;
cout << "ID asociado con thread2= " << t2_id << endl;
thread1.join();
thread2.join();
return 0;
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 17

Ejecución

Ejercicio 3. Aplique lock mutex al ejercicio 03 en la variable counter


Para aplicar lock mutex al ejercicio 03 en la variable counter, primero se debe crear un objeto
mutex y luego utilizarlo para proteger la variable counter. El objeto mutex se debe declarar en
el ámbito global para que ambos threads puedan acceder a él. Luego, se debe utilizar la
función lock() del objeto mutex antes de acceder a la variable counter y la función unlock()
después de acceder a ella. De esta manera, se asegura que solo un thread acceda a la variable
counter a la vez.

#include <iostream>
#include <thread>
#include <mutex>
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 18

using namespace std;

// variable global para ser protegida por el mutex


int counter = 0;

// mutex global para proteger la variable counter


mutex mtx;

void thread_func()
{
// Incrementa la variable counter
mtx.lock();
counter += 1;
cout << "Thread ID: " << this_thread::get_id()
<< ", Variable: " << counter
<< endl;
mtx.unlock();
}

int main()
{
thread t1(thread_func);
thread t2(thread_func);

t1.join();
t2.join();
return 0;
}
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 19

Ejecución
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 20

III. SOLUCIÓN DEL CUESTIONARIO


1 ¿La función sleep_until() es similar a sleep_for()?
La función sleep_until() es similar a sleep_for() que ambos bloquean la ejecución de un hilo durante
un período de tiempo específico. Sin embargo, existe una diferencia.
- La función sleep_for() especifica la duración del tiempo para dormir, mientras que la función
sleep_until() especifica la hora a la que el hilo debe despertarse. Esta función toma un
argumento de tipo std::chrono::duration que especifica la cantidad de tiempo durante la cual el
programa se va a dormir.
#include <iostream>
#include <chrono>
#include <thread>

int main() {
std::cout << "Comenzando..." << std::endl;

// Pausa durante 2 segundos


std::this_thread::sleep_for(std::chrono::seconds(2));

std::cout << "Después de la pausa de 2 segundos." << std::endl;

// Pausa durante 500 milisegundos


std::this_thread::sleep_for(std::chrono::milliseconds(500));

std::cout << "Después de la pausa de 500 milisegundos." << std::endl;

return 0;
}

- La función sleep_until() bloquea la ejecución de un hilo hasta que se alcanza el tiempo


especificado.Esta función toma un argumento de tipo std::chrono::time_point y pausará la
ejecución del programa hasta que se alcance ese momento en el tiempo.

#include <iostream>
#include <chrono>
#include <thread>

int main() {
std::cout << "Comenzando..." << std::endl;

// Obtener el momento actual


auto ahora = std::chrono::steady_clock::now();

// Pausa hasta 5 segundos en el futuro


auto futuro = ahora + std::chrono::seconds(5);
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 21

std::this_thread::sleep_until(futuro);

std::cout << "Después de la pausa hasta el momento en el futuro." <<


std::endl;

// Pausa hasta 1 segundo en el futuro


futuro = ahora + std::chrono::seconds(1);
std::this_thread::sleep_until(futuro);

std::cout << "Después de la pausa hasta 1 segundo en el futuro." <<


std::endl;

return 0;
}

Ambas funciones pueden bloquearse durante un período mayor que el tiempo especificado debido a
actividades de programación o retrasos en la contención de recursos.
También vale la pena señalar que sleep_for() está definido en el encabezado <thread>, mientras que
sleep_until() está definido en el encabezado <chrono>.

2 ¿La versión 17 de c++ podría compilar los codigos mostrados en esta guia?
Los códigos están escritos en C++11 o versiones posteriores, por lo que deberían ser compatibles con
la versión C++17 del lenguaje. La versión C++17 trajo muchas mejoras en la gestión de hilos y la
concurrencia, por lo que los ejercicios que hemos realizo deberían funcionar en un entorno de
compilación compatible con C++17.
Tan solo debemos asegurarnos de compilar los programas utilizando un compilador que sea
compatible con C++17, como GCC 7 o versiones posteriores, y usa la bandera -std=c++17 o superior al
compilar:
Para compilar los programas, se puede usar el siguiente comando:

g++ -std=c++17 ejercicio01.cpp -o ejercicio01

REFERENCIAS Y BIBLIOGRAFÍA
UNIVERSIDAD NACIONAL DE SAN AGUSTIN
FACULTAD DE INGENIERÍA DE PRODUCCIÓN Y SERVICIOS
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMA

Formato: Guía de Práctica de Laboratorio / Talleres / Centros de Simulación


Aprobación: 2022/03/01 Código: GUIA-PRLE-001 Página: 22

[1] Ivancea. 30 01 2017 C++ Threads (Hilos): online, Available:


https://code0x66.blogspot.com/2017/01/cthreads-hilos.html
[2] W. Tyler, Taojunsen, K Sharkey, M. B., M. Jones, G. Hogenson and S. Cai, 16 06 2023 Clase Thread: online,
Available: https://learn.microsoft.com/es-es/cpp/standard-library/thread-class?view=msvc-170

También podría gustarte