SlideShare una empresa de Scribd logo
1 de 79
Descargar para leer sin conexión
Taller de
Programaci´on Paralela
Concurrencia y nuevas caracter´ısticas en
C++11
Resumen trabajo de
investigaci´on 1/2014
Universidad de Santiago de Chile
Taller de Programaci´on Paralela
Profesor: Fernando Rannou
Ayudante: Sebasti´an Vizcay
sebastian.vizcay@usach.cl
Sebasti´an Vizcay June 16, 2015 1/79
Taller de
Programaci´on Paralela
Concurrencia en C++11
Tabla de contenidos
El header thread
El header mutex
El header condition variable
El header atomix
El header future
Compilaci´on
Sebasti´an Vizcay June 16, 2015 2/79
Taller de
Programaci´on Paralela
Thread
Principales caracter´ısticas
Comienza su ejecuci´on desde el momento en que se declara una
variable del tipo thread.
La forma m´as sencilla de indicar el c´odigo a ejecutar, es pas´andole al
constructor el nombre de la funci´on deseada.
Otras alternativas son especificar un m´etodo de un objeto, un
m´etodo est´atico de una clase,
Se DEBE SIEMPRE decidir si se desea esperar a que la nueva hebra
finalice su trabajo o si es que se desea permitir que corra libremente.
Sebasti´an Vizcay June 16, 2015 3/79
Taller de
Programaci´on Paralela
Thread
Join o detach
Si se desea esperar a que la nueva hebra finalice su trabajo antes de
llamar al destructor, llamaremos al m´etodo join del objeto thread
recien creado.
En caso en que se decide dejar a la nueva hebra correr de forma
completamente independiente, perrmiti´endonos incluso a que la
hebra principal finalice su trabajo y libere sus variables locales,
llamaremos al m´etodo detach.
En el caso en que se llame al m´etodo deatch, la nueva hebra de
ejecuci´on se desliga del objeto thread que reci´en creamos y se
continua ejecutando en background como un daemon.
Sebasti´an Vizcay June 16, 2015 4/79
Taller de
Programaci´on Paralela
Thread
M´as sobre detach
Si se desliga la hebra de ejecuci´on del objeto thread con detach y la
hebra principal ejecutando main finaliza, no se puede asegurar si la
nueva hebra de ejecuci´on continuar´a ejecut´andose.
Caso espec´ıfico: salidas a cout o a ficheros no son realizadas por la
segunda hebra si es que la primera finaliza la ejecuci´on de main.
Tampoco es reportada su ejecuci´on con el comando ps H (comando
que muestra la lista de procesos/hebras ejecut´andose).
Acorde a cppreference.com, ejecuci´on de la segunda hebra deber´ıa
continuar independientemente.
Sebasti´an Vizcay June 16, 2015 5/79
Taller de
Programaci´on Paralela
Thread
Ejemplo b´asico
#include <thread>
Nombre de una funci´on.
Uso de join.
1 # include <thread>
2 void foo ( ) ;
3 i n t main ( i n t argc , char ∗argv [ ] ) {
4 std : : thread myThread ( foo ) ;
5 myThread . j o i n ( ) ;
6 return 0;
7 }
Sebasti´an Vizcay June 16, 2015 6/79
Taller de
Programaci´on Paralela
Thread
Segundo ejemplo: funci´on con par´ametros
NOTA: se env´ıan copias de los argumentos aun cuando el prototipo
de la funci´on declare que recibe referencias como par´ametros.
1 # include <thread>
2 void foo ( i n t a , i n t b ) ;
3 i n t main ( i n t argc , char ∗argv [ ] ) {
4 i n t x = 5 , y = 10;
5 std : : thread myThread ( foo , x , y ) ;
6 myThread . j o i n ( ) ;
7 return 0;
8 }
Sebasti´an Vizcay June 16, 2015 7/79
Taller de
Programaci´on Paralela
Thread
Tercer ejemplo: m´etodo de un objeto
Recordar que un m´etodo no es m´as que una funci´on que tiene como
primer par´ametro impl´ıcito un puntero constante al objeto llamado
this.
1 class MyClass {
2 public :
3 MyClass ( ) ;
4 ˜ MyClass ( ) ;
5 method1 ( i n t x ) ;
6 };
Sebasti´an Vizcay June 16, 2015 8/79
Taller de
Programaci´on Paralela
Thread
Tercer ejemplo: m´etodo de un objeto
Recordar que un m´etodo no es m´as que una funci´on que tiene como
primer par´ametro impl´ıcito un puntero constante al objeto llamado
this.
1 # include <thread>
2 # include ” myclass . hpp ”
3 i n t main ( i n t argc , char ∗argv [ ] ) {
4 MyClass myObject ( ) ;
5 i n t number = 5;
6 std : : thread myThread (&MyClass : : method1 , &myObject , number ) ;
7 myThread . j o i n ( ) ;
8 return 0;
9 }
Sebasti´an Vizcay June 16, 2015 9/79
Taller de
Programaci´on Paralela
Thread
Cuarto ejemplo: funci´on con par´ametros de tipo referencias
#include <functional>para usar las funciones ref y cref.
Usar ref para enviar la variable por referencia y cref para cuando la
referencia fue declarada como const.
1 # include <thread>
2 # include <functional>
3 void foo ( i n t &a , const i n t &b ) ;
4 i n t main ( i n t argc , char ∗argv [ ] ) {
5 i n t x = 5 , y = 10;
6 std : : thread myThread ( foo , std : : r e f ( x ) , std : : cref ( y ) ) ;
7 myThread . j o i n ( ) ;
8 return 0;
9 }
Sebasti´an Vizcay June 16, 2015 10/79
Taller de
Programaci´on Paralela
Thread
Quinto ejemplo: crear un objeto con hebra de ejecuci´on propia
Se debe declarar un atributo miembro del tipo thread dentro de la
clase.
Se llama al constructor de thread, indicando el m´etodo a ejecutar
utilizando la nueva hebra de ejecuci´on, al momento en que se
construye un objeto de la clase.
Se invoca al m´etodo join del objeto thread dentro del destructor de
la clase, el cual ser´a ejecutado una vez que se acabe el scope del
objeto concurrente o a trav´es de una llamada expl´ıcita a delete.
Sebasti´an Vizcay June 16, 2015 11/79
Taller de
Programaci´on Paralela
Thread
Quinto ejemplo: crear un objeto con hebra de ejecuci´on propia
1 # include <thread>
2
3 class Task {
4 public :
5 Task ( ) ;
6 ˜ Task ( ) ;
7
8 private :
9 std : : thread privateThread ;
10 void main ( ) ;
11 };
Sebasti´an Vizcay June 16, 2015 12/79
Taller de
Programaci´on Paralela
Thread
Quinto ejemplo: crear un objeto con hebra de ejecuci´on propia
1 # include ” task . hpp ”
2
3 Task : : Task ( ) {
4 privateThread = std : : thread (&Task : : main , t h i s ) ;
5 }
6
7 Task : : ˜ Task ( ) {
8 privateThread . j o i n ( ) ;
9 }
Sebasti´an Vizcay June 16, 2015 13/79
Taller de
Programaci´on Paralela
Thread
Qu´e es lo que se env´ıa realmente al constructor de la clase thread?
Cuando se crea un objeto thread y se indica una funci´on en conjunto
con los argumentos que necesita, lo que se env´ıa realmente al
constructor es la funci´on retornada por la utilidad bind.
Bind es una utilidad que nos permite generar funciones a partir de
otra funci´on, la cual es utilizada como plantilla.
Bind puede ligar valores a los par´ametros que son esperados por la
funci´on plantilla.
Sebasti´an Vizcay June 16, 2015 14/79
Taller de
Programaci´on Paralela
Thread
Usando bind para generar funciones
1 i n t sum( i n t a , i n t b ) {
2 return a + b ;
3 }
4
5 i n t sum34 ( ) {
6 return 3 + 4;
7 }
1 i n t sumA4( i n t a ) {
2 return a + 4;
3 }
4
5 i n t sum3B( i n t b ) {
6 return 3 + b ;
7 }
Sebasti´an Vizcay June 16, 2015 15/79
Taller de
Programaci´on Paralela
Thread
Usando bind para generar funciones
1 # include <functional>
2 i n t main ( i n t argc , char ∗argv [ ] ) {
3 auto bindSum34 = std : : bind (sum, 3 , 4 ) ;
4 auto bindSumA4 = std : : bind (sum, std : : placeholders : : 1 , 4 ) ;
5 auto bindSum3B = std : : bind (sum, 3 , std : : placeholders : : 1 ) ;
6 std : : cout << sum(3 , 4) << std : : endl ;
7 std : : cout << bindSum34 ( ) << std : : endl ;
8 std : : cout << bindSumA4 (3) << std : : endl ;
9 std : : cout << bindSum3B (4) << std : : endl ;
10
11 return 0;
12 }
Sebasti´an Vizcay June 16, 2015 16/79
Taller de
Programaci´on Paralela
Thread
Comentarios adicionales sobre bind
Tanto bind como placeholders est´an declarados en el header
functional.
Se pueden especificar placeholders adicionales. 1 hace referencia
al primer par´ametro, 2 al segundo y as´ı sucesivamente.
Las variables que reciben la funci´on retornada por bind funcionan
exactamente igual que las funciones ordinarias, y deben invocarse
especificando una lista de argumentos encerrada entre par´entesis.
Sebasti´an Vizcay June 16, 2015 17/79
Taller de
Programaci´on Paralela
Thread
Comentarios adicionales sobre bind
No necesitamos explicitar el tipo de valor retornado por bind en el
momento de declarar las variables. Una de las nuevas
caracter´ısticas de C++11 es el uso de auto para dejar al compilador
que realice estas detecciones.
El uso de bind es ´util para modificar el signature de funciones a las
cuales no tenemos acceso para modificarlas, como por ejemplo
algoritmos provistos por la stl en el header algorithms.
Sebasti´an Vizcay June 16, 2015 18/79
Taller de
Programaci´on Paralela
Thread
Identificando a una hebra
Adem´as de los m´etodos join y detach, los objetos del tipo thread
poseen un tercer m´etodo que resulta de inter´es, el m´etodo get id.
El m´etodo get id retorno un identificador ´unico de la hebra de
ejecuci´on.
ID retornado resulta ser una secuencia num´erica larga poco
amigable para ser recordada.
El ID retornado por get id puede ser reutilizado a medida en que se
van creando y destruyendo las hebras de ejecuci´on.
Se aconseja asignar manualmente IDs ´unicos a cada thread,
agregando a la lista de par´ametros una variable num´erica que sea
utilizada como identificador.
Sebasti´an Vizcay June 16, 2015 19/79
Taller de
Programaci´on Paralela
Thread
Identificando a una hebra
La funci´on get id del scope this thread no es m´as que una funci´on
que invoca al m´etodo get id del objeto thread actualmente
ejecutando la l´ınea particular de c´odigo.
1 # include <thread>
2 void foo ( i n t t i d ) ;
3 i n t main ( i n t argc , char ∗argv [ ] ) {
4 i n t id = 0;
5 std : : thread myThread ( foo , id ) ;
6 myThread . j o i n ( ) ;
7
8 return 0;
9 }
Sebasti´an Vizcay June 16, 2015 20/79
Taller de
Programaci´on Paralela
Thread
Identificando a una hebra
1 void foo ( i n t t i d ) {
2 std : : cout << ”my id : ” << std : : t h i s t h r e a d : : g e t i d ( ) ;
3 std : : cout << std : : endl ;
4 std : : cout << ” manual id : ” << t i d << std : : endl ;
5 }
Listing 1: output
1 my id : 140150155630464
2 manual id : 0
Sebasti´an Vizcay June 16, 2015 21/79
Taller de
Programaci´on Paralela
Thread
Otras utilidades del namespace this thread
El namespace this thread agrupa un conjunto de funciones b´asicas
que resultan ser ´utiles para mecanismos de planificaci´on de hebras.
Adem´as de la funci´on get id, se encuentran las funciones sleep for,
sleep until y yield.
Todas estas funciones hacen referencia a la hebra actual que se
encuentra ejecut´andose.
Sebasti´an Vizcay June 16, 2015 22/79
Taller de
Programaci´on Paralela
Thread
Otras utilidades del namespace this thread
La funci´on yield sirve para indicar a la implementaci´on que
buscamos que se realice una replanificaci´on del scheduling de
hebras, es decir, se da la oportunidad a que se ejecuten otras
hebras.
No se puede especificar hebras en particular (la funci´on no recibe
ning´un par´ametro).
No se asegura que otra hebra entre a ejecutarse. Yield debe verse
como una sugerencia de replanificaci´on.
Sebasti´an Vizcay June 16, 2015 23/79
Taller de
Programaci´on Paralela
Thread
Otras utilidades del namespace this thread
Uso de sleep y usleep para suspender la ejecuci´on de una hebra es
considerado obsoleto.
Uso del namespace chrono para definir periodos de tiempo de forma
flexible (precisi´on de segundos,minutos, horas, microsegundos,
nanosegundos, etc.).
Funciones sleep for y sleep until toman como argumento un
periodo de tiempo y un instante en el tiempo respectivamente. El
primero es un tiempo relativo al tiempo exacto en que se invoca a
sleep for y el segundo es un tiempo absoluto, independiente del
tiempo en que se invoc´o a sleep until.
Sebasti´an Vizcay June 16, 2015 24/79
Taller de
Programaci´on Paralela
Thread
Ejemplo de uso de sleep for
1 # include <chrono>
2 # include <thread>
3
4 i n t main ( i n t argc , char ∗argv [ ] ) {
5 std : : chrono : : milliseconds duration (5000); / / 5 seconds
6 std : : t h i s t h r e a d : : sleep for ( duration ) ;
7
8 return 0;
9 }
Sebasti´an Vizcay June 16, 2015 25/79
Taller de
Programaci´on Paralela
Thread
Consideraci´on con respecto a locks y similares
Si se est´a trabajando con variables de condici´on o locks, el invocar
a yield o a a alg´un tipo de sleep no liberar´a el lock del mutex que se
hab´ıa adquirido, por lo que se debe tener cuidado a la hora de llamar
a estas funciones habiendo adquirido alg´un lock previamente.
Sebasti´an Vizcay June 16, 2015 26/79
Taller de
Programaci´on Paralela
Mutex
Exclusi´on mutua - Mutex
Para hacer uso de exclusi´on mutua, se debe incluir el header
<mutex>.
Ejemplo de uso: deseamos obtener una salida limpia en cout, es
decir, que no se mezcle la escritura de hebras concurrentes.
Sebasti´an Vizcay June 16, 2015 27/79
Taller de
Programaci´on Paralela
Mutex
Ejemplo b´asico
1 # include <mutex>
2 void p r i n t ( i n t value1 , i n t value2 , i n t value3 ) {
3 s t a t i c std : : mutex m;
4 m. lock ( ) ;
5 std : : cout << value1 << ” ” ;
6 std : : cout << value2 << ” ” ;
7 std : : cout << value3 << ” ” ;
8 std : : cout << std : : endl ;
9 m. unlock ( ) ;
10 }
Sebasti´an Vizcay June 16, 2015 28/79
Taller de
Programaci´on Paralela
Mutex
Analizando el ejemplo anterior
Cada vez que una hebra intenta invocar la funci´on print, esta
intentar´a adquirir el lock del mutex.
Una vez que una hebra adquiere el lock, ´esta entra a lo que es
conocido como secci´on cr´ıtica. La secci´on cr´ıtica en este caso son
las l´ıneas de c´odigo que imprimen los 3 valores en la pantalla.
Ninguna otra hebra puede entrar a la secci´on cr´ıtica mientras el lock
se encuentre tomado.
Una vez que la hebra que adquiri´o el lock termina de ejecutar la
secci´on cr´ıtica, ´esta libera el lock manualmente realizando un
unlock.
Sebasti´an Vizcay June 16, 2015 29/79
Taller de
Programaci´on Paralela
Mutex
Analizando el ejemplo anterior
NOTA: la variable mutex, la cual provee los m´etodos lock y unlock, es
declarada static con el fin de que se cree solo una variable del tipo
mutex com´un para todas las invocaciones a print.
Cuando se hace uso de locks se serializa el c´odigo. Atomix es una
alternativa al uso de locks pero solo algunos tipos de variables
permiten ser manejados a nivel at´omico, adem´as de ser solo algunas
operaciones las que efectivamente se permiten que se realicen de
forma at´omica.
Notar que si llega ocurrir un error dentro de la secci´on cr´ıtica, la
hebra que se encuentre ejecutando la secci´on cr´ıtica nunca
alcanzar´a a ejecutar el unlock del mutex, produciendo que la
aplicaci´on se cuelge completamente.
Sebasti´an Vizcay June 16, 2015 30/79
Taller de
Programaci´on Paralela
Mutex
Ejemplo 2: Alternativa try-catch
1 # include <mutex>
2 # include <exception>
3 void p r i n t ( i n t value1 , i n t value2 , i n t value3 ) {
4 s t a t i c std : : mutex m;
5 m. lock ( ) ;
6 t r y {
7 / / c r i t i c a l section
8 m. unlock ( ) ;
9 } catch ( std : : exception &e ) {
10 m. unlock ( ) ;
11 }
12 }
Sebasti´an Vizcay June 16, 2015 31/79
Taller de
Programaci´on Paralela
Mutex
Mutex con RAII
Una alternativa mejor ser´ıa que el lock se liberase autom´aticamente
una vez que finaliza el scope del mutex. As´ı el programador no
tendr´ıa que preocuparse de liberar manualmente el lock poni´endose
en cada escenario en que el bloque de c´odigo de la secci´on cr´ıtica
pudiese fallar.
Dentro de C++11 se sugiere el uso de manejadores de locks. RAII
(Resource Acquisition Is Initialization) es un t´ermino que se refiere a
que la adquisici´on de un recurso est´a limitada por el tiempo de vida
del objeto que lo adquiere. Este idea tambi´en puede ser encontrada
como CADRe (Constructor Acquires, Destructor Release).
RAII provee encapsulaci´on y seguridad en caso que ocurran
excepciones.
Sebasti´an Vizcay June 16, 2015 32/79
Taller de
Programaci´on Paralela
Mutex
Ejemplo 3: Uso de lock guard como manejador de locks
1 # include <mutex>
2 void p r i n t ( i n t value1 , i n t value2 , i n t value3 ) {
3 s t a t i c std : : mutex m;
4 std : : lock guard<std : : mutex> lock (m) ;
5 / / c r i t i c a l section
6 }
Sebasti´an Vizcay June 16, 2015 33/79
Taller de
Programaci´on Paralela
Mutex
Usando lock guard
El constructor de lock guard invoca al m´etodo lock del mutex.
En el instante en que se acaba el scope del objeto lock guard o
alguna excepci´on es arrojada, el destructor del lock guard realiza
una llamada al m´etodo unlock del mutex.
Sebasti´an Vizcay June 16, 2015 34/79
Taller de
Programaci´on Paralela
Mutex
Usando unique lock
Existe otro manejador de mutex aparte del lock guard, llamado
unique lock. La diferencia entre unique lock y guard lock, es que el
´ultimo, solo permite la invocaci´on del lock del mutex al momento de
construcci´on del objeto guard lock, es decir, el manejador
unique lock es m´as flexible permitiendo mayor control sobre la
invocaci´on de los m´etodos lock y unlock.
Un objeto del tipo unique lock permite ser contruido sin necesidad de
llamar al m´etodo lock del mutex interno. De todas formas se asegura
que al momento en que se acaba su scope, el mutex se encontrar´a
liberado.
Sebasti´an Vizcay June 16, 2015 35/79
Taller de
Programaci´on Paralela
Mutex
Usando unique lock
Cuando se utilizan variables de condici´on es necesario tener que
liberar el lock antes de que la hebra se bloquee al tener que ejecutar
el wait. El uso de guard lock resulta ser no suficiente para tales
casos debido a que se deben especificar locks y unlocks adicionales
a los momento en que se construye y destruye el manejador de
locks.
Como regla, solo cuando se realicen llamados expl´ıcitos al m´etodo
lock del mutex se deber´a tambi´en llamar expl´ıcitamente al m´etodo
unlock.
Sebasti´an Vizcay June 16, 2015 36/79
Taller de
Programaci´on Paralela
Mutex
Tipos de mutex
Mutex: El mutex tradicional. Si una misma hebra llama al m´etodo
lock de un mutex dos veces consecutivas sin hacer un
unlock, la segunda llamada producir´a un deadlock.
Recursive mutex: Permite que el lock sea obtenido m´as de una vez por la
misma hebra (similar a la caracter´ıstica de exclusi´on mutua
en µC++).
Sebasti´an Vizcay June 16, 2015 37/79
Taller de
Programaci´on Paralela
Mutex
Tipos de mutex
Timed mutex: Mutex que adem´as de los m´etodos lock y unlock, proveen
tambi´en los m´etodos try lock for y try lock until, los
cuales intentan durante una determinada cantidad de
tiempo adquirir el lock. Ambos m´etodos retornan despu´es
de tal periodo independientemente de si lograron o no
adquirirlo. En caso en que la adquisici´on fue existosa, los
m´etodos retornan verdadero y cierran el lock (recordar
hacer el posterior unlock). En caso que expire el timeout,
los m´etodos retornan falso y no hay nada que se necesite
liberar.
Recursive timed mutex: Es la uni´on de las dos caracter´ısticas anteriores.
Sebasti´an Vizcay June 16, 2015 38/79
Taller de
Programaci´on Paralela
Mutex
Spinlock con try lock
El m´etodo try lock es com´un a todos los tipos de mutex. Este
m´etodo puede ser utilizado para hacer un spinlock.
Recordar que cuando una hebra encuentra que el lock est´a tomado,
´esta se bloquea esperando a que se libere el lock. Un spinlock, en
vez de bloquear a la hebra, comienza a hacer lo que es conocido
como busy-waiting.
Sebasti´an Vizcay June 16, 2015 39/79
Taller de
Programaci´on Paralela
Mutex
Spinlock con try lock
1 # include <mutex>
2 i n t main ( i n t argc , char ∗argv [ ] ) {
3 std : : mutex mutex ;
4 while ( ! mutex . t r y l o c k ( ) ) {
5 ; / / busy−waiting
6 }
7 / / c r i t i c a l section
8 mutex . unlock ( ) ;
9
10 return 0;
11 }
Sebasti´an Vizcay June 16, 2015 40/79
Taller de
Programaci´on Paralela
Mutex
Table : Resumen tipo de mutex y m´etodos
M´etodo Mutex Recursive mutex Timed mutex Recursive timed mutex
lock X X X X
unlock X X X X
try lock X X X X
try lock for X X
try lock until X X
Sebasti´an Vizcay June 16, 2015 41/79
Taller de
Programaci´on Paralela
Mutex
Table : Resumen tipo de manejadores de mutex y m´etodos
M´etodo Lock guard Unique lock
lock X
unlock X
try lock X
try lock for X
try lock until X
Lock guard obviamente no posee ning´un m´etodo dado que el lock y
unlock lo realiza al instante en que se construye y destruye el objeto.
Unique lock posee todos los m´etodos pero para invocar a los dos
´ultimos, el mutex manejado debe ser del tipo timed.
Sebasti´an Vizcay June 16, 2015 42/79
Taller de
Programaci´on Paralela
Mutex
Simulando un monitor de µC++
1 # include <mutex>
2
3 class Monitor {
4 public :
5 Monitor ( ) ;
6 ˜ Monitor ( ) ;
7
8 private :
9 std : : recursive mutex mutex ;
10
11 void method1 ( ) ;
12 void method2 ( ) ;
13 };
Sebasti´an Vizcay June 16, 2015 43/79
Taller de
Programaci´on Paralela
Mutex
Simulando un monitor de µC++
1 # include ” monitor . hpp ”
2
3 void Monitor : : method1 ( ) {
4 std : : unique lock<std : : recursive mutex> lock ( mutex ) ;
5 / / c r i t i c a l section
6 }
7
8 void Monitor : : method2 ( ) {
9 std : : unique lock<std : : recursive mutex> lock ( mutex ) ;
10 / / c r i t i c a l section
11 }
Sebasti´an Vizcay June 16, 2015 44/79
Taller de
Programaci´on Paralela
Mutex
Funciones adicionales
Dentro del header mutex se pueden encontrar las siguientes
funciones adicionales: lock, try lock, call once.
La funci´on lock toma como par´ametro una lista de objetos del tipo
mutex de los cuales intentar´a obtener el lock. En caso en que no se
logren obtener todos los locks, la funci´on realizar´a un rollback
quedando todos los locks nuevamente liberados. En caso de ´exito, la
funci´on retornar´a y la hebra podr´a acceder a la secci´on cr´ıtica. Una
vez que se ejecut´o la secci´on cr´ıtica, se deben liberar de forma
manual todos los locks que se obtuvieron.
Sebasti´an Vizcay June 16, 2015 45/79
Taller de
Programaci´on Paralela
Mutex
Uso de la funci´on lock
El orden en que se especifican los mutex no es importante. La
funci´on fue dise˜nada de tal forma para aliviar al programador el tener
que escribir la adquisici´on de locks en un determinado orden con el
fin evitar deadlocks.
1 # include <mutex>
2 std : : mutex mutex1 , mutex2 ;
3 void task1 ( ) {
4 std : : lock ( mutex1 , mutex2 ) ;
5 / / c r i t i c a l section
6 mutex1 . unlock ( ) ;
7 mutex2 . unlock ( ) ;
8 }
1
2
3 void task2 ( ) {
4 std : : lock ( mutex2 , mutex1 ) ;
5 / / c r i t i c a l section
6 mutex1 . unlock ( ) ;
7 mutex2 . unlock ( ) ;
8 }
Sebasti´an Vizcay June 16, 2015 46/79
Taller de
Programaci´on Paralela
Mutex
Funciones adicionales
La funci´on try lock funciona de forma similar a la funci´on lock pero
invocar´a al m´etodo try lock de todos los mutex que se le indiquen
dentro de la lista de par´ametros.
Try lock retornar´a -1 en caso en que obtenga todos los locks
satisfatoriamente o un n´umero entero indicando el ´ındice del primer
mutex del cual no logr´o adquirir su lock.
Sebasti´an Vizcay June 16, 2015 47/79
Taller de
Programaci´on Paralela
Mutex
Funciones adicionales: call once y once flag
Si tenemos una funci´on que ser´a ejecutada por m´ultiples hebras y
deseamos que cierta parte de la funci´on sea solo ejecutada por tan
solo una hebra, podemos utilizar la funci´on call once para
especificar las l´ıneas de c´odigo que deben ejecutarse solo una vez.
La funci´on call once recibe como par´ametro una funci´on, un objeto
funcional, un lambda o cualquer otro objeto que se comporte como
funci´on para indicar el c´odigo a ejecutar.
Call once necesita verificar una variable del tipo once flag para ver
si el c´odigo ya fue o no ejecutado por alguna otra hebra.
Sebasti´an Vizcay June 16, 2015 48/79
Taller de
Programaci´on Paralela
Mutex
Uso de call once
1 # include <mutex>
2
3 std : : once flag f l a g ;
4
5 void task ( ) {
6 std : : call once ( flag , [ ] ( ) {
7 std : : cout << ” p r i n t j u s t once ” << std : : endl ;
8 });
9 std : : cout << ” p r i n t every single time ” << std : : endl ;
10 }
Sebasti´an Vizcay June 16, 2015 49/79
Taller de
Programaci´on Paralela
Condition variable
Caracter´ısticas principales
#include <condition variable>
Las variables de condici´on manejan una lista de hebras que se
encuentran a la espera de que otra hebra notifique alg´un evento.
Toda hebra que necesita esperar por alguna variable de condici´on,
DEBE haber adquirido previamente el lock.
El lock es liberado una vez que la hebra comienza a esperar en la
variable de condici´on.
El lock es obtenido nuevamente una vez que la hebra es
se˜nalizada para continuar.
Sebasti´an Vizcay June 16, 2015 50/79
Taller de
Programaci´on Paralela
Condition variable
Caracter´ısticas principales
El mutex DEBE ser manejado por el wrapper unique lock.
Si se desea utilizar otro tipo de wrapper, se debe utilizar una
variable de condici´on del tipo condition variable any.
Sebasti´an Vizcay June 16, 2015 51/79
Taller de
Programaci´on Paralela
Condition variable
Caracter´ısticas principales
Los m´etodos principales son wait, notify one y notify all.
El m´etodo wait bloquea a la hebra en espera del evento en particular.
El m´etodo notify one despertar´a a solo una hebra que se encuentre
en la cola de hebras esperando por el evento que representa la
variable de condici´on. En caso en que no haya ninguna hebra
esperando, no sucede nada en particular.
El m´etodo notify all despertar´a a todas las hebras esperando por tal
evento. Notar que las hebras despertadas a´un tendr´an que tomar el
lock nuevamente, por lo que la ejecuci´on de ellas y su acceso a la
secci´on critica sigue siendo serializado. De igual forma a notify one,
si no existe ninguna hebra en la cola de espera, no suceder´a nada
especial.
Sebasti´an Vizcay June 16, 2015 52/79
Taller de
Programaci´on Paralela
Condition variable
Caracter´ısticas principales
El m´etodo wait toma como primer par´ametro obligatorio el mutex del
cual debe liberar el lock antes de bloquearse.
El segundo parametro es opcional y corresponde a un predicado
(algo que puede evaluarse a true o false) que indicar´a si la hebra
debe efectivamente despertar o seguir bloqueada aun cuando se
haya despertado.
El especificar un predicado es equivalente a envolver la llamada a
wait con un while verificando por la negaci´on del predicado.
Sebasti´an Vizcay June 16, 2015 53/79
Taller de
Programaci´on Paralela
Condition variable
Especificando un predicado
1 std : : mutex mutex ;
2 std : : unique lock<std : : mutex> lock ( mutex ) ;
3 std : : c o n d i t i o n v a r i a b l e insertOne ;
4 while ( counter == 0) {
5 insertOne . wait ( lock ) ;
6 }
1 std : : mutex mutex ;
2 std : : unique lock<std : : mutex> lock ( mutex ) ;
3 std : : c o n d i t i o n v a r i a b l e insertOne ;
4 insertOne . wait ( lock , [ counter ] ( ) −> bool {
5 return counter != 0});
Sebasti´an Vizcay June 16, 2015 54/79
Taller de
Programaci´on Paralela
Condition variable
Spurious Wakes
Cuando no se especifica un predicado en el segundo par´ametro del
wait, hay que tener cuidado de envolver la llamada a wait con un
while y no con una simple instrucci´on if.
Una hebra puede despertar aun cuando no se haya realizado
ninguna se˜nalizaci´on a trav´es de alg´un notify. Esto es conocido
como spurious wakes (despertar err´oneo) y no pueden ser
predichos. Spurious wakes generalmente ocurren cuando la
biblioteca de hebras no puede asegurar que la hebra dormida no se
perder´a de alguna notificaci´on, por lo que decide despertarla para
evitar el riesgo.
Al utilizar un while o un predicado, nos aseguramos que la hebra
despierta solamente cuando corresponde.
Sebasti´an Vizcay June 16, 2015 55/79
Taller de
Programaci´on Paralela
Condition variable
Ejemplo completo de variables de condici´on
1 class Buffer {
2 public :
3 Buffer ( unsigned size = 0 ) ;
4 ˜ Buffer ( ) ;
5 void i n s e r t ( i n t item ) ;
6 i n t remove ( ) ;
7 private :
8 unsigned size ;
9 unsigned counter ;
10 i n t ∗items ;
11 std : : c o n d i t i o n a l v a r i a b l e removeOne , insertOne ;
12 std : : mutex mutex ;
13 };
Sebasti´an Vizcay June 16, 2015 56/79
Taller de
Programaci´on Paralela
Condition variable
Ejemplo completo de variables de condici´on
1 # include ” buffer . hpp ”
2 Buffer : : Buffer ( unsigned size ) : size ( size ) ,
3 counter (0) , items (new i n t [ size ] ) {}
4
5 Buffer : : ˜ Buffer ( ) {
6 delete [ ] items ;
7 }
Sebasti´an Vizcay June 16, 2015 57/79
Taller de
Programaci´on Paralela
Condition variable
Ejemplo completo de variables de condici´on
1 void Buffer : : i n s e r t ( i n t item ) {
2 std : : unique lock<std : : mutex> lock ( mutex ) ;
3 removeOne . wait ( lock , [ t h i s ] ( ) −> bool {
4 return counter != size ; } ) ;
5 items [ counter ] = item ;
6 counter ++;
7
8 insertOne . notify one ( ) ;
9 }
Sebasti´an Vizcay June 16, 2015 58/79
Taller de
Programaci´on Paralela
Condition variable
Ejemplo completo de variables de condici´on
1 void Buffer : : remove ( ) {
2 std : : unique lock<std : : mutex> lock ( mutex ) ;
3 while ( counter == 0) {
4 insertOne . wait ( lock ) ;
5 }
6 counter−−;
7 i n t item = items [ counter ] ;
8
9 removeOne . notify one ( ) ;
10
11 return item ;
12 }
Sebasti´an Vizcay June 16, 2015 59/79
Taller de
Programaci´on Paralela
Condition variable
Ejemplo completo de variables de condici´on
1 # include <thread>
2 # include ” buffer . hpp ”
3
4 void consumer ( i n t tid , Buffer & buffer ) {
5 i n t value = buffer . remove ( ) ;
6 std : : cout << ” thread=” << t i d ;
7 std : : cout << ” took the value ” ;
8 std : : cout << value << std : : endl ;
9 }
10
11 void producer ( i n t tid , Buffer & buffer ) {
12 buffer . i n s e r t ( t i d ) ;
13 }
Sebasti´an Vizcay June 16, 2015 60/79
Taller de
Programaci´on Paralela
Condition variable
Ejemplo completo de variables de condici´on
1 i n t main ( i n t argc , char ∗argv [ ] ) {
2 Buffer buffer ( 5 ) ;
3 std : : thread consumers [1000] , producers [1000];
4
5 f o r ( unsigned i = 0; i < 1000; i ++) {
6 consumers [ i ] = std : : thread ( consumer , i , std : : r e f ( buffer ) ) ;
7 producers [ i ] = std : : thread ( producer , i , std : : r e f ( buffer ) ) ;
8 }
9 f o r ( unsigned i = 0; i < 1000; i ++) {
10 consumers [ i ] . j o i n ( ) ;
11 producers [ i ] . j o i n ( ) ;
12 }
13 return 0;
14 }
Sebasti´an Vizcay June 16, 2015 61/79
Taller de
Programaci´on Paralela
Atomic
Caracter´ısticas principales
#include <atomic>.
Atomic permite la implementaci´on de algoritmos libres de locks.
Operaciones at´omicas presentan mejor performance que su
equivalente utilizando locks.
Uno debe especificar el tipo de variable que ser´a tratada de forma
at´omica (thread-safe).
Va a depender de la implementaci´on el mecanismo utilizado para
asegurar que la operaci´on sea thread-safe, pudiendo incluso llegar a
utilizarse locks. Generalmente para tipos de datos b´asicos, las
implementaciones quedan libres de locks.
Sebasti´an Vizcay June 16, 2015 62/79
Taller de
Programaci´on Paralela
Atomic
Caracter´ısticas principales
Los m´etodos principales son load y store.
El m´etodo load funciona como los m´etodos get y simplemente
retorna el valor actual. El m´etodo store setea un nuevo valor a la
variable del tipo atomic.
Existe otro m´etodo llamado exchange, el cual setea un nuevo valor a
la variable at´omica y al mismo tiempo retorna el valor antiguo.
Sebasti´an Vizcay June 16, 2015 63/79
Taller de
Programaci´on Paralela
Atomic
Ejemplo de atomic
1 # include <atomic>
2 i n t main ( i n t argc , char ∗argv [ ] ) {
3 i n t i n i t i a l V a l u e = 5;
4 std : : atomic<int> atomic ( i n i t i a l V a l u e ) ;
5 i n t newValue = 10;
6 atomic . store ( newValue ) ;
7 i n t lastValue = atomic . load ( ) ;
8
9 return 0;
10 }
Sebasti´an Vizcay June 16, 2015 64/79
Taller de
Programaci´on Paralela
Atomic
Caracter´ısticas principales
Los m´etodos load y store permiten adem´as especificar el modelo de
memoria a utilizar (secuencialmente consistente es el modelo por
defecto).
Los modelos de memoria describen si los accesos a memoria
pueden ser optimizados ya sea por el compilador o por el procesador.
Si el modelo es relajado, se permite que las operaciones sean
reordenadas o combinadas con el fin de mejorar el performance.
El modelo m´as estricto es el secuencialmente consistente, el cual es
el por defecto.
Sebasti´an Vizcay June 16, 2015 65/79
Taller de
Programaci´on Paralela
Atomic
Ejemplo del m´etodo exchange
1 # include <atomic>
2 std : : atomic<bool> winner ( false ) ;
3
4 void race ( ) {
5 i f ( ! winner . exchange ( true ) ) {
6 std : : cout << ” winner id = ” ;
7 std : : cout << std : : t h i s t h r e a d : : g e t i d ( ) << std : : endl ;
8 }
9 }
Sebasti´an Vizcay June 16, 2015 66/79
Taller de
Programaci´on Paralela
Atomic
Ejemplo del m´etodo exchange
1 # include <thread>
2
3 i n t main ( i n t argc , char ∗argv [ ] ) {
4 std : : thread threads [ 1 0 ] ;
5
6 f o r ( unsigned i = 0; i < 10; i ++) {
7 threads [ i ] = std : : thread ( race ) ;
8 }
9
10 f o r ( unsigned i = 0; i < 10; i ++) {
11 threads [ i ] . j o i n ( ) ;
12 }
13
14 return 0;
15 } Sebasti´an Vizcay June 16, 2015 67/79
Taller de
Programaci´on Paralela
Future
Comunicaci´on as´ıncrona con Future
#include <future>.
La funci´on async nos permite lanzar la ejecuci´on de una hebra sin
que necesariamente comience su ejecuci´on inmediatamente.
Si la funci´on que lanzamos as´ıncronamente retornar alg´un valor,
podemos consultar por el valor retornado almacen´andolo en una
variable del tipo future.
La clase future es una clase template (de igual forma que atomic), en
donde se debe especificar el tipo de dato que ser´a utilizado en el
template. El tipo de dato tiene que corresponderse con el tipo de
dato retornado por la funci´on lanzada as´ıncronamente.
Sebasti´an Vizcay June 16, 2015 68/79
Taller de
Programaci´on Paralela
Future
Comunicaci´on as´ıncrona con Future
En general se puede ver el header future como un conjunto de
utilidades que permiten acceso as´ıncrono a valores que ser´an
seteados por proveedores corriendo en otras hebras de ejecuci´on.
El m´etodo get es el m´etodo principal de los objetos del tipo future. El
m´etodo get es el que obliga a que el valor sea finalmente
calculado/seteado en caso en que todav´ıa no lo haya sido. En el
caso en que el valor todav´ıa no se encuentre disponible, la hebra
ejecutando el m´etodo get se bloquear´a hasta que el valor se
encuentre disponible.
La hebra calculando el valor puede setear una excepci´on en el valor
a retornar, lanz´andose efectivamente al momento en que se realiza
la llamada a get.
Sebasti´an Vizcay June 16, 2015 69/79
Taller de
Programaci´on Paralela
Future
Ejemplo de future
1 # include <future>
2
3 i n t add ( i n t a , i n t b ) {
4 return a+b ;
5 }
6
7 i n t main ( i n t argc , char ∗argv [ ] ) {
8 std : : future<int> r e s u l t ( std : : async ( add , 2 , 4) ) ;
9
10 std : : cout << r e s u l t . get ( ) << std : : endl ;
11
12 return 0;
13 }
Sebasti´an Vizcay June 16, 2015 70/79
Taller de
Programaci´on Paralela
Future
Proveedores para future
La funci´on async es la m´as f´acil de utilizar para proveer de valores a
las variables del tipo future.
Adem´as de la funci´on async, se cuenta con los objetos de las clases
promise y packaged task.
La clase promise es una clase template que permite proveer de
valores o de excepciones a variables del tipo future.
Los m´etodos principales de un objeto promise son get future,
set value y set exception.
Sebasti´an Vizcay June 16, 2015 71/79
Taller de
Programaci´on Paralela
Future
Proveedores para future - promise
El m´etodo get future es la forma en la que se vincula el future con
el promise.
Se debe invocar al m´etodo get future cuando se est´a
construyendo/incializando el objeto del tipo future. Posterior a esta
invocaci´on, el objeto del tipo promise y future poseer´an un estado
compartido.
Solo puede retornarse un future por promise.
Una vez que se ha generado el v´ınculo, se espera que en alg´un
momento el promise setee el valor esperado por el future, o que
simplemente setee alguna excepci´on para que sea lanzada por el
future al intentar recuperar el valor con el m´etodo get.
Sebasti´an Vizcay June 16, 2015 72/79
Taller de
Programaci´on Paralela
Future
Proveedores para future - promise
Si se llegase a ejecutar el destructor de la variable de tipo promise
sin que ´esta haya alcanzado a setear alg´un valor o excepci´on, el
estado de la informaci´on pasar´a a estar como disponible y la
invocaci´on del m´etodo get del future retornar´a. En el momento en
que retorne get, se lanzar´a una excepci´on del tipo future error.
Cuando en alguna hebra de ejecuci´on se invoca a una de los
m´etodos set value o set exception, el estado cambia a disponible y
la hebra bloqueada en la invocaci´on a get retorna.
Sebasti´an Vizcay June 16, 2015 73/79
Taller de
Programaci´on Paralela
Future
Ejemplo de future y promise
1 # include <future>
2 # include <thread>
3 # include <exception>
4
5 void p r i n t ( std : : future<int> & future ) {
6 t r y {
7 std : : cout << future . get ( ) << std : : endl ;
8 } catch ( std : : exception & e ) {
9 std : : cerr << e . what ( ) << std : : endl ;
10 }
11 }
Sebasti´an Vizcay June 16, 2015 74/79
Taller de
Programaci´on Paralela
Future
Ejemplo de future y promise
1 i n t main ( i n t argc , char ∗argv [ ] ) {
2 std : : promise<int> promise ;
3 std : : future<int> future ( promise . g e t f u t u r e ( ) ) ;
4 std : : thread thread ( p r i nt , std : : r e f ( future ) ) ;
5 promise . set value ( 1 5 ) ;
6
7 thread . j o i n ( ) ;
8
9 return 0;
10 }
Sebasti´an Vizcay June 16, 2015 75/79
Taller de
Programaci´on Paralela
Future
Proveedores para future - packaged task
La clase packaged task funciona de forma similar al promise pero
se diferencian en que la primera envuelve a un objeto llamable (una
funci´on, una expresi´on lambda, un functor etc.).
El valor retornado por el objeto funcional es lo que se setea como
valor a almacenar en el future, es decir, ya no es necesario
especificar el valor a trav´es de alguna llamada a set value como se
hac´ıa en los objetos promise.
La clase packaged task es una clase template y dentro de los
par´ametros del template se debe especificar el tipo de retorno de la
funci´on y los tipos de variables de los par´ametros.
Sebasti´an Vizcay June 16, 2015 76/79
Taller de
Programaci´on Paralela
Future
Ejemplo de future y packaged task
1 i n t add ( i n t a , i n t b ) {
2 return a+b ;
3 }
4
5 i n t main ( i n t argc , char ∗argv [ ] ) {
6 std : : packaged task<i n t ( int , i n t )> task ( add ) ;
7 std : : future<int> future ( task . g e t f u t u r e ( ) ) ;
8 std : : thread thread ( std : : move( task ) , 3 , 4 ) ;
9 std : : cout << future . get ( ) << std : : endl ;
10 thread . j o i n ( ) ;
11 return 0;
12 }
Sebasti´an Vizcay June 16, 2015 77/79
Taller de
Programaci´on Paralela
Compilaci´on
C++11 utilza hebras provistas por la plataforma.
pthreads Unix.
win32 threads Windows
Consultar por la biblioteca de hebras utilizadas por el compilador.
$ g++ -v (buscar por la l´ınea Thread model).
Compilar con flag -std=c++11 o -std=c++0x, y enlazar con pthreads.
g++ -c -Wall -std=c++11 -o main.o main.cpp
g++ -o program.exe main.o -pthreads
En caso de error al enlazar con pthread.
g++ -o program.exe main.o -pthreads -Wl,–no-as-needed
Sebasti´an Vizcay June 16, 2015 78/79
Taller de
Programaci´on Paralela
Consultas
Sebasti´an Vizcay June 16, 2015 79/79

Más contenido relacionado

La actualidad más candente

Polimorfismo
PolimorfismoPolimorfismo
PolimorfismoUVM
 
Presen iii 26 funciones
Presen iii  26 funcionesPresen iii  26 funciones
Presen iii 26 funcionesRafaeloRivas
 
Bibliotecas o librerias_para_c_
Bibliotecas o librerias_para_c_Bibliotecas o librerias_para_c_
Bibliotecas o librerias_para_c_Oziel Solis Juarez
 
Realidad Aumentada 01 documentacion tapir
Realidad Aumentada 01 documentacion tapirRealidad Aumentada 01 documentacion tapir
Realidad Aumentada 01 documentacion tapirAgustín Hv
 
Que es una directiva de preprocesador
Que es una directiva de preprocesadorQue es una directiva de preprocesador
Que es una directiva de preprocesadorAndrew King
 
SCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/OSCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/Oflekoso
 
Funciones definidas por el usuario
Funciones definidas por el usuarioFunciones definidas por el usuario
Funciones definidas por el usuarioUVM
 
Informe tecnico u4 final
Informe tecnico u4 finalInforme tecnico u4 final
Informe tecnico u4 finalIrving Che
 
Estructura programa c++
Estructura programa c++Estructura programa c++
Estructura programa c++UVM
 
Apuntes1 elementos del lenguaje c
Apuntes1 elementos del lenguaje cApuntes1 elementos del lenguaje c
Apuntes1 elementos del lenguaje cZalimanunezc
 

La actualidad más candente (19)

02 - Tipos de datos escalares en Python 3
02 - Tipos de datos escalares en Python 302 - Tipos de datos escalares en Python 3
02 - Tipos de datos escalares en Python 3
 
05 - Funciones en lenguaje C
05 - Funciones en lenguaje C05 - Funciones en lenguaje C
05 - Funciones en lenguaje C
 
Polimorfismo
PolimorfismoPolimorfismo
Polimorfismo
 
Presen iii 26 funciones
Presen iii  26 funcionesPresen iii  26 funciones
Presen iii 26 funciones
 
Bibliotecas o librerias_para_c_
Bibliotecas o librerias_para_c_Bibliotecas o librerias_para_c_
Bibliotecas o librerias_para_c_
 
Presentacion Python
Presentacion  Python Presentacion  Python
Presentacion Python
 
Realidad Aumentada 01 documentacion tapir
Realidad Aumentada 01 documentacion tapirRealidad Aumentada 01 documentacion tapir
Realidad Aumentada 01 documentacion tapir
 
Viernes Tecnicos DTrace
Viernes Tecnicos DTraceViernes Tecnicos DTrace
Viernes Tecnicos DTrace
 
Que es una directiva de preprocesador
Que es una directiva de preprocesadorQue es una directiva de preprocesador
Que es una directiva de preprocesador
 
SCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/OSCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/O
 
Dotnetmania 9 pag_21_29
Dotnetmania 9 pag_21_29Dotnetmania 9 pag_21_29
Dotnetmania 9 pag_21_29
 
Funciones definidas por el usuario
Funciones definidas por el usuarioFunciones definidas por el usuario
Funciones definidas por el usuario
 
Introduccion a Python
Introduccion a PythonIntroduccion a Python
Introduccion a Python
 
Manejo de la memoria
Manejo de la memoriaManejo de la memoria
Manejo de la memoria
 
Informe tecnico u4 final
Informe tecnico u4 finalInforme tecnico u4 final
Informe tecnico u4 final
 
Estructura programa c++
Estructura programa c++Estructura programa c++
Estructura programa c++
 
Apuntes1 elementos del lenguaje c
Apuntes1 elementos del lenguaje cApuntes1 elementos del lenguaje c
Apuntes1 elementos del lenguaje c
 
Clase1_Python-CTIC
Clase1_Python-CTICClase1_Python-CTIC
Clase1_Python-CTIC
 
C++
C++C++
C++
 

Destacado

Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...
Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...
Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...Deborah Tuggy
 
Maria actividad 7
Maria actividad 7Maria actividad 7
Maria actividad 7mafer2321
 
Multi Microsite Management
Multi Microsite ManagementMulti Microsite Management
Multi Microsite ManagementNico Rehmann
 
Anderson sneider tecnologuia e informatica
Anderson sneider tecnologuia e informaticaAnderson sneider tecnologuia e informatica
Anderson sneider tecnologuia e informaticaedwinroja
 
Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)
Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)
Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)Sascha Foerster
 
Tarea4 mariapaolamendez
Tarea4 mariapaolamendezTarea4 mariapaolamendez
Tarea4 mariapaolamendezPaolaMendez95_
 
Sistema óseo de vertebrados
Sistema óseo de vertebradosSistema óseo de vertebrados
Sistema óseo de vertebradosMarco Torrez
 
A3P Exec Overview Whitepaper
A3P Exec Overview WhitepaperA3P Exec Overview Whitepaper
A3P Exec Overview WhitepaperDavid Knox
 
It’s Just Social Media
It’s Just Social MediaIt’s Just Social Media
It’s Just Social MediaWill Patch
 
עדלאידע חולון 2011
עדלאידע חולון 2011עדלאידע חולון 2011
עדלאידע חולון 2011Holon Municipality
 
Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...
Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...
Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...Rahim Blak
 
SEOGuardian - Café en capsulas - Actualización anual
SEOGuardian - Café en capsulas - Actualización anualSEOGuardian - Café en capsulas - Actualización anual
SEOGuardian - Café en capsulas - Actualización anualBint
 
Likovna kultura 14
Likovna kultura 14Likovna kultura 14
Likovna kultura 14aco bojic
 
Likovna kultura 20
Likovna kultura 20Likovna kultura 20
Likovna kultura 20aco bojic
 
창조경제연구회 It를 통한 금융혁명 핀테크
창조경제연구회 It를 통한 금융혁명 핀테크창조경제연구회 It를 통한 금융혁명 핀테크
창조경제연구회 It를 통한 금융혁명 핀테크메가트렌드랩 megatrendlab
 

Destacado (20)

Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...
Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...
Hispanos en los EE.UU: La sociedad y cultura de hispanos en La Bahía de San F...
 
Maria actividad 7
Maria actividad 7Maria actividad 7
Maria actividad 7
 
Multi Microsite Management
Multi Microsite ManagementMulti Microsite Management
Multi Microsite Management
 
Bad ct 5_31 (1)
Bad ct 5_31 (1)Bad ct 5_31 (1)
Bad ct 5_31 (1)
 
Weltbevoelkerung
WeltbevoelkerungWeltbevoelkerung
Weltbevoelkerung
 
Anderson sneider tecnologuia e informatica
Anderson sneider tecnologuia e informaticaAnderson sneider tecnologuia e informatica
Anderson sneider tecnologuia e informatica
 
Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)
Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)
Posterslam: Suche nach den Nachkriegskindern (DH Summit 2015, Berlin)
 
Tarea4 mariapaolamendez
Tarea4 mariapaolamendezTarea4 mariapaolamendez
Tarea4 mariapaolamendez
 
Redes Sociales
Redes Sociales Redes Sociales
Redes Sociales
 
Sistema óseo de vertebrados
Sistema óseo de vertebradosSistema óseo de vertebrados
Sistema óseo de vertebrados
 
A3P Exec Overview Whitepaper
A3P Exec Overview WhitepaperA3P Exec Overview Whitepaper
A3P Exec Overview Whitepaper
 
It’s Just Social Media
It’s Just Social MediaIt’s Just Social Media
It’s Just Social Media
 
עדלאידע חולון 2011
עדלאידע חולון 2011עדלאידע חולון 2011
עדלאידע חולון 2011
 
Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...
Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...
Zrozumieć Social Media - Promocja wydarzeń przez social media. Rahim Blak dla...
 
SEOGuardian - Café en capsulas - Actualización anual
SEOGuardian - Café en capsulas - Actualización anualSEOGuardian - Café en capsulas - Actualización anual
SEOGuardian - Café en capsulas - Actualización anual
 
Likovna kultura 14
Likovna kultura 14Likovna kultura 14
Likovna kultura 14
 
Likovna kultura 20
Likovna kultura 20Likovna kultura 20
Likovna kultura 20
 
창조경제연구회 It를 통한 금융혁명 핀테크
창조경제연구회 It를 통한 금융혁명 핀테크창조경제연구회 It를 통한 금융혁명 핀테크
창조경제연구회 It를 통한 금융혁명 핀테크
 
Sass
SassSass
Sass
 
Madimed
MadimedMadimed
Madimed
 

Similar a C++11 Concurrency (20)

Rompiendo dependencias contenidas en ensamblados .NET mediante la refactoriza...
Rompiendo dependencias contenidas en ensamblados .NET mediante la refactoriza...Rompiendo dependencias contenidas en ensamblados .NET mediante la refactoriza...
Rompiendo dependencias contenidas en ensamblados .NET mediante la refactoriza...
 
Testing efectivo con pytest
Testing efectivo con pytestTesting efectivo con pytest
Testing efectivo con pytest
 
C# Nuevas características en C# 6
C# Nuevas características en C# 6C# Nuevas características en C# 6
C# Nuevas características en C# 6
 
Hebras
HebrasHebras
Hebras
 
El lenguaje C++ (1).ppt
El lenguaje C++ (1).pptEl lenguaje C++ (1).ppt
El lenguaje C++ (1).ppt
 
El lenguaje C++.ppt
El lenguaje C++.pptEl lenguaje C++.ppt
El lenguaje C++.ppt
 
Cplus
CplusCplus
Cplus
 
C++
C++C++
C++
 
Programación en c++
Programación en c++Programación en c++
Programación en c++
 
Funciones en C.docx
Funciones en C.docxFunciones en C.docx
Funciones en C.docx
 
Guía funciones
Guía funcionesGuía funciones
Guía funciones
 
Java básico
Java  básicoJava  básico
Java básico
 
Lenguaje c ++ guía para programadores
Lenguaje c ++  guía para programadoresLenguaje c ++  guía para programadores
Lenguaje c ++ guía para programadores
 
Framework .NET 3.5 10 Linq
Framework .NET 3.5 10 LinqFramework .NET 3.5 10 Linq
Framework .NET 3.5 10 Linq
 
Ejercicio de automatizacion IntelliJ+reporte.docx
Ejercicio de automatizacion IntelliJ+reporte.docxEjercicio de automatizacion IntelliJ+reporte.docx
Ejercicio de automatizacion IntelliJ+reporte.docx
 
Doc tutorial-c++
Doc tutorial-c++Doc tutorial-c++
Doc tutorial-c++
 
Doc tutorial-c++
Doc tutorial-c++Doc tutorial-c++
Doc tutorial-c++
 
Doc tutorial-c++
Doc tutorial-c++Doc tutorial-c++
Doc tutorial-c++
 
Doc tutorial-c++
Doc tutorial-c++Doc tutorial-c++
Doc tutorial-c++
 
Doc tutorial-c++
Doc tutorial-c++Doc tutorial-c++
Doc tutorial-c++
 

Último

RETO MES DE ABRIL .............................docx
RETO MES DE ABRIL .............................docxRETO MES DE ABRIL .............................docx
RETO MES DE ABRIL .............................docxAna Fernandez
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADauxsoporte
 
Herramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdfHerramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdfMARIAPAULAMAHECHAMOR
 
Plan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPEPlan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPELaura Chacón
 
30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdf30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdfgimenanahuel
 
Historia y técnica del collage en el arte
Historia y técnica del collage en el arteHistoria y técnica del collage en el arte
Historia y técnica del collage en el arteRaquel Martín Contreras
 
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptxPRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptxinformacionasapespu
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxjosetrinidadchavez
 
GLOSAS Y PALABRAS ACTO 2 DE ABRIL 2024.docx
GLOSAS  Y PALABRAS ACTO 2 DE ABRIL 2024.docxGLOSAS  Y PALABRAS ACTO 2 DE ABRIL 2024.docx
GLOSAS Y PALABRAS ACTO 2 DE ABRIL 2024.docxAleParedes11
 
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOSTEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOSjlorentemartos
 
Manual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdfManual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdfMaryRotonda1
 
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxLINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxdanalikcruz2000
 
2024 - Expo Visibles - Visibilidad Lesbica.pdf
2024 - Expo Visibles - Visibilidad Lesbica.pdf2024 - Expo Visibles - Visibilidad Lesbica.pdf
2024 - Expo Visibles - Visibilidad Lesbica.pdfBaker Publishing Company
 
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARONARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFAROJosé Luis Palma
 
codigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karinacodigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karinavergarakarina022
 
Lecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdadLecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdadAlejandrino Halire Ccahuana
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.amayarogel
 
programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para eventoDiegoMtsS
 

Último (20)

Power Point: "Defendamos la verdad".pptx
Power Point: "Defendamos la verdad".pptxPower Point: "Defendamos la verdad".pptx
Power Point: "Defendamos la verdad".pptx
 
RETO MES DE ABRIL .............................docx
RETO MES DE ABRIL .............................docxRETO MES DE ABRIL .............................docx
RETO MES DE ABRIL .............................docx
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDAD
 
Herramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdfHerramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdf
 
Plan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPEPlan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPE
 
30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdf30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdf
 
Historia y técnica del collage en el arte
Historia y técnica del collage en el arteHistoria y técnica del collage en el arte
Historia y técnica del collage en el arte
 
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptxPRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
 
GLOSAS Y PALABRAS ACTO 2 DE ABRIL 2024.docx
GLOSAS  Y PALABRAS ACTO 2 DE ABRIL 2024.docxGLOSAS  Y PALABRAS ACTO 2 DE ABRIL 2024.docx
GLOSAS Y PALABRAS ACTO 2 DE ABRIL 2024.docx
 
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOSTEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
 
Manual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdfManual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdf
 
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxLINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
 
2024 - Expo Visibles - Visibilidad Lesbica.pdf
2024 - Expo Visibles - Visibilidad Lesbica.pdf2024 - Expo Visibles - Visibilidad Lesbica.pdf
2024 - Expo Visibles - Visibilidad Lesbica.pdf
 
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARONARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
 
codigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karinacodigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karina
 
Lecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdadLecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdad
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.
 
programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para evento
 
Repaso Pruebas CRECE PR 2024. Ciencia General
Repaso Pruebas CRECE PR 2024. Ciencia GeneralRepaso Pruebas CRECE PR 2024. Ciencia General
Repaso Pruebas CRECE PR 2024. Ciencia General
 

C++11 Concurrency

  • 1. Taller de Programaci´on Paralela Concurrencia y nuevas caracter´ısticas en C++11 Resumen trabajo de investigaci´on 1/2014 Universidad de Santiago de Chile Taller de Programaci´on Paralela Profesor: Fernando Rannou Ayudante: Sebasti´an Vizcay sebastian.vizcay@usach.cl Sebasti´an Vizcay June 16, 2015 1/79
  • 2. Taller de Programaci´on Paralela Concurrencia en C++11 Tabla de contenidos El header thread El header mutex El header condition variable El header atomix El header future Compilaci´on Sebasti´an Vizcay June 16, 2015 2/79
  • 3. Taller de Programaci´on Paralela Thread Principales caracter´ısticas Comienza su ejecuci´on desde el momento en que se declara una variable del tipo thread. La forma m´as sencilla de indicar el c´odigo a ejecutar, es pas´andole al constructor el nombre de la funci´on deseada. Otras alternativas son especificar un m´etodo de un objeto, un m´etodo est´atico de una clase, Se DEBE SIEMPRE decidir si se desea esperar a que la nueva hebra finalice su trabajo o si es que se desea permitir que corra libremente. Sebasti´an Vizcay June 16, 2015 3/79
  • 4. Taller de Programaci´on Paralela Thread Join o detach Si se desea esperar a que la nueva hebra finalice su trabajo antes de llamar al destructor, llamaremos al m´etodo join del objeto thread recien creado. En caso en que se decide dejar a la nueva hebra correr de forma completamente independiente, perrmiti´endonos incluso a que la hebra principal finalice su trabajo y libere sus variables locales, llamaremos al m´etodo detach. En el caso en que se llame al m´etodo deatch, la nueva hebra de ejecuci´on se desliga del objeto thread que reci´en creamos y se continua ejecutando en background como un daemon. Sebasti´an Vizcay June 16, 2015 4/79
  • 5. Taller de Programaci´on Paralela Thread M´as sobre detach Si se desliga la hebra de ejecuci´on del objeto thread con detach y la hebra principal ejecutando main finaliza, no se puede asegurar si la nueva hebra de ejecuci´on continuar´a ejecut´andose. Caso espec´ıfico: salidas a cout o a ficheros no son realizadas por la segunda hebra si es que la primera finaliza la ejecuci´on de main. Tampoco es reportada su ejecuci´on con el comando ps H (comando que muestra la lista de procesos/hebras ejecut´andose). Acorde a cppreference.com, ejecuci´on de la segunda hebra deber´ıa continuar independientemente. Sebasti´an Vizcay June 16, 2015 5/79
  • 6. Taller de Programaci´on Paralela Thread Ejemplo b´asico #include <thread> Nombre de una funci´on. Uso de join. 1 # include <thread> 2 void foo ( ) ; 3 i n t main ( i n t argc , char ∗argv [ ] ) { 4 std : : thread myThread ( foo ) ; 5 myThread . j o i n ( ) ; 6 return 0; 7 } Sebasti´an Vizcay June 16, 2015 6/79
  • 7. Taller de Programaci´on Paralela Thread Segundo ejemplo: funci´on con par´ametros NOTA: se env´ıan copias de los argumentos aun cuando el prototipo de la funci´on declare que recibe referencias como par´ametros. 1 # include <thread> 2 void foo ( i n t a , i n t b ) ; 3 i n t main ( i n t argc , char ∗argv [ ] ) { 4 i n t x = 5 , y = 10; 5 std : : thread myThread ( foo , x , y ) ; 6 myThread . j o i n ( ) ; 7 return 0; 8 } Sebasti´an Vizcay June 16, 2015 7/79
  • 8. Taller de Programaci´on Paralela Thread Tercer ejemplo: m´etodo de un objeto Recordar que un m´etodo no es m´as que una funci´on que tiene como primer par´ametro impl´ıcito un puntero constante al objeto llamado this. 1 class MyClass { 2 public : 3 MyClass ( ) ; 4 ˜ MyClass ( ) ; 5 method1 ( i n t x ) ; 6 }; Sebasti´an Vizcay June 16, 2015 8/79
  • 9. Taller de Programaci´on Paralela Thread Tercer ejemplo: m´etodo de un objeto Recordar que un m´etodo no es m´as que una funci´on que tiene como primer par´ametro impl´ıcito un puntero constante al objeto llamado this. 1 # include <thread> 2 # include ” myclass . hpp ” 3 i n t main ( i n t argc , char ∗argv [ ] ) { 4 MyClass myObject ( ) ; 5 i n t number = 5; 6 std : : thread myThread (&MyClass : : method1 , &myObject , number ) ; 7 myThread . j o i n ( ) ; 8 return 0; 9 } Sebasti´an Vizcay June 16, 2015 9/79
  • 10. Taller de Programaci´on Paralela Thread Cuarto ejemplo: funci´on con par´ametros de tipo referencias #include <functional>para usar las funciones ref y cref. Usar ref para enviar la variable por referencia y cref para cuando la referencia fue declarada como const. 1 # include <thread> 2 # include <functional> 3 void foo ( i n t &a , const i n t &b ) ; 4 i n t main ( i n t argc , char ∗argv [ ] ) { 5 i n t x = 5 , y = 10; 6 std : : thread myThread ( foo , std : : r e f ( x ) , std : : cref ( y ) ) ; 7 myThread . j o i n ( ) ; 8 return 0; 9 } Sebasti´an Vizcay June 16, 2015 10/79
  • 11. Taller de Programaci´on Paralela Thread Quinto ejemplo: crear un objeto con hebra de ejecuci´on propia Se debe declarar un atributo miembro del tipo thread dentro de la clase. Se llama al constructor de thread, indicando el m´etodo a ejecutar utilizando la nueva hebra de ejecuci´on, al momento en que se construye un objeto de la clase. Se invoca al m´etodo join del objeto thread dentro del destructor de la clase, el cual ser´a ejecutado una vez que se acabe el scope del objeto concurrente o a trav´es de una llamada expl´ıcita a delete. Sebasti´an Vizcay June 16, 2015 11/79
  • 12. Taller de Programaci´on Paralela Thread Quinto ejemplo: crear un objeto con hebra de ejecuci´on propia 1 # include <thread> 2 3 class Task { 4 public : 5 Task ( ) ; 6 ˜ Task ( ) ; 7 8 private : 9 std : : thread privateThread ; 10 void main ( ) ; 11 }; Sebasti´an Vizcay June 16, 2015 12/79
  • 13. Taller de Programaci´on Paralela Thread Quinto ejemplo: crear un objeto con hebra de ejecuci´on propia 1 # include ” task . hpp ” 2 3 Task : : Task ( ) { 4 privateThread = std : : thread (&Task : : main , t h i s ) ; 5 } 6 7 Task : : ˜ Task ( ) { 8 privateThread . j o i n ( ) ; 9 } Sebasti´an Vizcay June 16, 2015 13/79
  • 14. Taller de Programaci´on Paralela Thread Qu´e es lo que se env´ıa realmente al constructor de la clase thread? Cuando se crea un objeto thread y se indica una funci´on en conjunto con los argumentos que necesita, lo que se env´ıa realmente al constructor es la funci´on retornada por la utilidad bind. Bind es una utilidad que nos permite generar funciones a partir de otra funci´on, la cual es utilizada como plantilla. Bind puede ligar valores a los par´ametros que son esperados por la funci´on plantilla. Sebasti´an Vizcay June 16, 2015 14/79
  • 15. Taller de Programaci´on Paralela Thread Usando bind para generar funciones 1 i n t sum( i n t a , i n t b ) { 2 return a + b ; 3 } 4 5 i n t sum34 ( ) { 6 return 3 + 4; 7 } 1 i n t sumA4( i n t a ) { 2 return a + 4; 3 } 4 5 i n t sum3B( i n t b ) { 6 return 3 + b ; 7 } Sebasti´an Vizcay June 16, 2015 15/79
  • 16. Taller de Programaci´on Paralela Thread Usando bind para generar funciones 1 # include <functional> 2 i n t main ( i n t argc , char ∗argv [ ] ) { 3 auto bindSum34 = std : : bind (sum, 3 , 4 ) ; 4 auto bindSumA4 = std : : bind (sum, std : : placeholders : : 1 , 4 ) ; 5 auto bindSum3B = std : : bind (sum, 3 , std : : placeholders : : 1 ) ; 6 std : : cout << sum(3 , 4) << std : : endl ; 7 std : : cout << bindSum34 ( ) << std : : endl ; 8 std : : cout << bindSumA4 (3) << std : : endl ; 9 std : : cout << bindSum3B (4) << std : : endl ; 10 11 return 0; 12 } Sebasti´an Vizcay June 16, 2015 16/79
  • 17. Taller de Programaci´on Paralela Thread Comentarios adicionales sobre bind Tanto bind como placeholders est´an declarados en el header functional. Se pueden especificar placeholders adicionales. 1 hace referencia al primer par´ametro, 2 al segundo y as´ı sucesivamente. Las variables que reciben la funci´on retornada por bind funcionan exactamente igual que las funciones ordinarias, y deben invocarse especificando una lista de argumentos encerrada entre par´entesis. Sebasti´an Vizcay June 16, 2015 17/79
  • 18. Taller de Programaci´on Paralela Thread Comentarios adicionales sobre bind No necesitamos explicitar el tipo de valor retornado por bind en el momento de declarar las variables. Una de las nuevas caracter´ısticas de C++11 es el uso de auto para dejar al compilador que realice estas detecciones. El uso de bind es ´util para modificar el signature de funciones a las cuales no tenemos acceso para modificarlas, como por ejemplo algoritmos provistos por la stl en el header algorithms. Sebasti´an Vizcay June 16, 2015 18/79
  • 19. Taller de Programaci´on Paralela Thread Identificando a una hebra Adem´as de los m´etodos join y detach, los objetos del tipo thread poseen un tercer m´etodo que resulta de inter´es, el m´etodo get id. El m´etodo get id retorno un identificador ´unico de la hebra de ejecuci´on. ID retornado resulta ser una secuencia num´erica larga poco amigable para ser recordada. El ID retornado por get id puede ser reutilizado a medida en que se van creando y destruyendo las hebras de ejecuci´on. Se aconseja asignar manualmente IDs ´unicos a cada thread, agregando a la lista de par´ametros una variable num´erica que sea utilizada como identificador. Sebasti´an Vizcay June 16, 2015 19/79
  • 20. Taller de Programaci´on Paralela Thread Identificando a una hebra La funci´on get id del scope this thread no es m´as que una funci´on que invoca al m´etodo get id del objeto thread actualmente ejecutando la l´ınea particular de c´odigo. 1 # include <thread> 2 void foo ( i n t t i d ) ; 3 i n t main ( i n t argc , char ∗argv [ ] ) { 4 i n t id = 0; 5 std : : thread myThread ( foo , id ) ; 6 myThread . j o i n ( ) ; 7 8 return 0; 9 } Sebasti´an Vizcay June 16, 2015 20/79
  • 21. Taller de Programaci´on Paralela Thread Identificando a una hebra 1 void foo ( i n t t i d ) { 2 std : : cout << ”my id : ” << std : : t h i s t h r e a d : : g e t i d ( ) ; 3 std : : cout << std : : endl ; 4 std : : cout << ” manual id : ” << t i d << std : : endl ; 5 } Listing 1: output 1 my id : 140150155630464 2 manual id : 0 Sebasti´an Vizcay June 16, 2015 21/79
  • 22. Taller de Programaci´on Paralela Thread Otras utilidades del namespace this thread El namespace this thread agrupa un conjunto de funciones b´asicas que resultan ser ´utiles para mecanismos de planificaci´on de hebras. Adem´as de la funci´on get id, se encuentran las funciones sleep for, sleep until y yield. Todas estas funciones hacen referencia a la hebra actual que se encuentra ejecut´andose. Sebasti´an Vizcay June 16, 2015 22/79
  • 23. Taller de Programaci´on Paralela Thread Otras utilidades del namespace this thread La funci´on yield sirve para indicar a la implementaci´on que buscamos que se realice una replanificaci´on del scheduling de hebras, es decir, se da la oportunidad a que se ejecuten otras hebras. No se puede especificar hebras en particular (la funci´on no recibe ning´un par´ametro). No se asegura que otra hebra entre a ejecutarse. Yield debe verse como una sugerencia de replanificaci´on. Sebasti´an Vizcay June 16, 2015 23/79
  • 24. Taller de Programaci´on Paralela Thread Otras utilidades del namespace this thread Uso de sleep y usleep para suspender la ejecuci´on de una hebra es considerado obsoleto. Uso del namespace chrono para definir periodos de tiempo de forma flexible (precisi´on de segundos,minutos, horas, microsegundos, nanosegundos, etc.). Funciones sleep for y sleep until toman como argumento un periodo de tiempo y un instante en el tiempo respectivamente. El primero es un tiempo relativo al tiempo exacto en que se invoca a sleep for y el segundo es un tiempo absoluto, independiente del tiempo en que se invoc´o a sleep until. Sebasti´an Vizcay June 16, 2015 24/79
  • 25. Taller de Programaci´on Paralela Thread Ejemplo de uso de sleep for 1 # include <chrono> 2 # include <thread> 3 4 i n t main ( i n t argc , char ∗argv [ ] ) { 5 std : : chrono : : milliseconds duration (5000); / / 5 seconds 6 std : : t h i s t h r e a d : : sleep for ( duration ) ; 7 8 return 0; 9 } Sebasti´an Vizcay June 16, 2015 25/79
  • 26. Taller de Programaci´on Paralela Thread Consideraci´on con respecto a locks y similares Si se est´a trabajando con variables de condici´on o locks, el invocar a yield o a a alg´un tipo de sleep no liberar´a el lock del mutex que se hab´ıa adquirido, por lo que se debe tener cuidado a la hora de llamar a estas funciones habiendo adquirido alg´un lock previamente. Sebasti´an Vizcay June 16, 2015 26/79
  • 27. Taller de Programaci´on Paralela Mutex Exclusi´on mutua - Mutex Para hacer uso de exclusi´on mutua, se debe incluir el header <mutex>. Ejemplo de uso: deseamos obtener una salida limpia en cout, es decir, que no se mezcle la escritura de hebras concurrentes. Sebasti´an Vizcay June 16, 2015 27/79
  • 28. Taller de Programaci´on Paralela Mutex Ejemplo b´asico 1 # include <mutex> 2 void p r i n t ( i n t value1 , i n t value2 , i n t value3 ) { 3 s t a t i c std : : mutex m; 4 m. lock ( ) ; 5 std : : cout << value1 << ” ” ; 6 std : : cout << value2 << ” ” ; 7 std : : cout << value3 << ” ” ; 8 std : : cout << std : : endl ; 9 m. unlock ( ) ; 10 } Sebasti´an Vizcay June 16, 2015 28/79
  • 29. Taller de Programaci´on Paralela Mutex Analizando el ejemplo anterior Cada vez que una hebra intenta invocar la funci´on print, esta intentar´a adquirir el lock del mutex. Una vez que una hebra adquiere el lock, ´esta entra a lo que es conocido como secci´on cr´ıtica. La secci´on cr´ıtica en este caso son las l´ıneas de c´odigo que imprimen los 3 valores en la pantalla. Ninguna otra hebra puede entrar a la secci´on cr´ıtica mientras el lock se encuentre tomado. Una vez que la hebra que adquiri´o el lock termina de ejecutar la secci´on cr´ıtica, ´esta libera el lock manualmente realizando un unlock. Sebasti´an Vizcay June 16, 2015 29/79
  • 30. Taller de Programaci´on Paralela Mutex Analizando el ejemplo anterior NOTA: la variable mutex, la cual provee los m´etodos lock y unlock, es declarada static con el fin de que se cree solo una variable del tipo mutex com´un para todas las invocaciones a print. Cuando se hace uso de locks se serializa el c´odigo. Atomix es una alternativa al uso de locks pero solo algunos tipos de variables permiten ser manejados a nivel at´omico, adem´as de ser solo algunas operaciones las que efectivamente se permiten que se realicen de forma at´omica. Notar que si llega ocurrir un error dentro de la secci´on cr´ıtica, la hebra que se encuentre ejecutando la secci´on cr´ıtica nunca alcanzar´a a ejecutar el unlock del mutex, produciendo que la aplicaci´on se cuelge completamente. Sebasti´an Vizcay June 16, 2015 30/79
  • 31. Taller de Programaci´on Paralela Mutex Ejemplo 2: Alternativa try-catch 1 # include <mutex> 2 # include <exception> 3 void p r i n t ( i n t value1 , i n t value2 , i n t value3 ) { 4 s t a t i c std : : mutex m; 5 m. lock ( ) ; 6 t r y { 7 / / c r i t i c a l section 8 m. unlock ( ) ; 9 } catch ( std : : exception &e ) { 10 m. unlock ( ) ; 11 } 12 } Sebasti´an Vizcay June 16, 2015 31/79
  • 32. Taller de Programaci´on Paralela Mutex Mutex con RAII Una alternativa mejor ser´ıa que el lock se liberase autom´aticamente una vez que finaliza el scope del mutex. As´ı el programador no tendr´ıa que preocuparse de liberar manualmente el lock poni´endose en cada escenario en que el bloque de c´odigo de la secci´on cr´ıtica pudiese fallar. Dentro de C++11 se sugiere el uso de manejadores de locks. RAII (Resource Acquisition Is Initialization) es un t´ermino que se refiere a que la adquisici´on de un recurso est´a limitada por el tiempo de vida del objeto que lo adquiere. Este idea tambi´en puede ser encontrada como CADRe (Constructor Acquires, Destructor Release). RAII provee encapsulaci´on y seguridad en caso que ocurran excepciones. Sebasti´an Vizcay June 16, 2015 32/79
  • 33. Taller de Programaci´on Paralela Mutex Ejemplo 3: Uso de lock guard como manejador de locks 1 # include <mutex> 2 void p r i n t ( i n t value1 , i n t value2 , i n t value3 ) { 3 s t a t i c std : : mutex m; 4 std : : lock guard<std : : mutex> lock (m) ; 5 / / c r i t i c a l section 6 } Sebasti´an Vizcay June 16, 2015 33/79
  • 34. Taller de Programaci´on Paralela Mutex Usando lock guard El constructor de lock guard invoca al m´etodo lock del mutex. En el instante en que se acaba el scope del objeto lock guard o alguna excepci´on es arrojada, el destructor del lock guard realiza una llamada al m´etodo unlock del mutex. Sebasti´an Vizcay June 16, 2015 34/79
  • 35. Taller de Programaci´on Paralela Mutex Usando unique lock Existe otro manejador de mutex aparte del lock guard, llamado unique lock. La diferencia entre unique lock y guard lock, es que el ´ultimo, solo permite la invocaci´on del lock del mutex al momento de construcci´on del objeto guard lock, es decir, el manejador unique lock es m´as flexible permitiendo mayor control sobre la invocaci´on de los m´etodos lock y unlock. Un objeto del tipo unique lock permite ser contruido sin necesidad de llamar al m´etodo lock del mutex interno. De todas formas se asegura que al momento en que se acaba su scope, el mutex se encontrar´a liberado. Sebasti´an Vizcay June 16, 2015 35/79
  • 36. Taller de Programaci´on Paralela Mutex Usando unique lock Cuando se utilizan variables de condici´on es necesario tener que liberar el lock antes de que la hebra se bloquee al tener que ejecutar el wait. El uso de guard lock resulta ser no suficiente para tales casos debido a que se deben especificar locks y unlocks adicionales a los momento en que se construye y destruye el manejador de locks. Como regla, solo cuando se realicen llamados expl´ıcitos al m´etodo lock del mutex se deber´a tambi´en llamar expl´ıcitamente al m´etodo unlock. Sebasti´an Vizcay June 16, 2015 36/79
  • 37. Taller de Programaci´on Paralela Mutex Tipos de mutex Mutex: El mutex tradicional. Si una misma hebra llama al m´etodo lock de un mutex dos veces consecutivas sin hacer un unlock, la segunda llamada producir´a un deadlock. Recursive mutex: Permite que el lock sea obtenido m´as de una vez por la misma hebra (similar a la caracter´ıstica de exclusi´on mutua en µC++). Sebasti´an Vizcay June 16, 2015 37/79
  • 38. Taller de Programaci´on Paralela Mutex Tipos de mutex Timed mutex: Mutex que adem´as de los m´etodos lock y unlock, proveen tambi´en los m´etodos try lock for y try lock until, los cuales intentan durante una determinada cantidad de tiempo adquirir el lock. Ambos m´etodos retornan despu´es de tal periodo independientemente de si lograron o no adquirirlo. En caso en que la adquisici´on fue existosa, los m´etodos retornan verdadero y cierran el lock (recordar hacer el posterior unlock). En caso que expire el timeout, los m´etodos retornan falso y no hay nada que se necesite liberar. Recursive timed mutex: Es la uni´on de las dos caracter´ısticas anteriores. Sebasti´an Vizcay June 16, 2015 38/79
  • 39. Taller de Programaci´on Paralela Mutex Spinlock con try lock El m´etodo try lock es com´un a todos los tipos de mutex. Este m´etodo puede ser utilizado para hacer un spinlock. Recordar que cuando una hebra encuentra que el lock est´a tomado, ´esta se bloquea esperando a que se libere el lock. Un spinlock, en vez de bloquear a la hebra, comienza a hacer lo que es conocido como busy-waiting. Sebasti´an Vizcay June 16, 2015 39/79
  • 40. Taller de Programaci´on Paralela Mutex Spinlock con try lock 1 # include <mutex> 2 i n t main ( i n t argc , char ∗argv [ ] ) { 3 std : : mutex mutex ; 4 while ( ! mutex . t r y l o c k ( ) ) { 5 ; / / busy−waiting 6 } 7 / / c r i t i c a l section 8 mutex . unlock ( ) ; 9 10 return 0; 11 } Sebasti´an Vizcay June 16, 2015 40/79
  • 41. Taller de Programaci´on Paralela Mutex Table : Resumen tipo de mutex y m´etodos M´etodo Mutex Recursive mutex Timed mutex Recursive timed mutex lock X X X X unlock X X X X try lock X X X X try lock for X X try lock until X X Sebasti´an Vizcay June 16, 2015 41/79
  • 42. Taller de Programaci´on Paralela Mutex Table : Resumen tipo de manejadores de mutex y m´etodos M´etodo Lock guard Unique lock lock X unlock X try lock X try lock for X try lock until X Lock guard obviamente no posee ning´un m´etodo dado que el lock y unlock lo realiza al instante en que se construye y destruye el objeto. Unique lock posee todos los m´etodos pero para invocar a los dos ´ultimos, el mutex manejado debe ser del tipo timed. Sebasti´an Vizcay June 16, 2015 42/79
  • 43. Taller de Programaci´on Paralela Mutex Simulando un monitor de µC++ 1 # include <mutex> 2 3 class Monitor { 4 public : 5 Monitor ( ) ; 6 ˜ Monitor ( ) ; 7 8 private : 9 std : : recursive mutex mutex ; 10 11 void method1 ( ) ; 12 void method2 ( ) ; 13 }; Sebasti´an Vizcay June 16, 2015 43/79
  • 44. Taller de Programaci´on Paralela Mutex Simulando un monitor de µC++ 1 # include ” monitor . hpp ” 2 3 void Monitor : : method1 ( ) { 4 std : : unique lock<std : : recursive mutex> lock ( mutex ) ; 5 / / c r i t i c a l section 6 } 7 8 void Monitor : : method2 ( ) { 9 std : : unique lock<std : : recursive mutex> lock ( mutex ) ; 10 / / c r i t i c a l section 11 } Sebasti´an Vizcay June 16, 2015 44/79
  • 45. Taller de Programaci´on Paralela Mutex Funciones adicionales Dentro del header mutex se pueden encontrar las siguientes funciones adicionales: lock, try lock, call once. La funci´on lock toma como par´ametro una lista de objetos del tipo mutex de los cuales intentar´a obtener el lock. En caso en que no se logren obtener todos los locks, la funci´on realizar´a un rollback quedando todos los locks nuevamente liberados. En caso de ´exito, la funci´on retornar´a y la hebra podr´a acceder a la secci´on cr´ıtica. Una vez que se ejecut´o la secci´on cr´ıtica, se deben liberar de forma manual todos los locks que se obtuvieron. Sebasti´an Vizcay June 16, 2015 45/79
  • 46. Taller de Programaci´on Paralela Mutex Uso de la funci´on lock El orden en que se especifican los mutex no es importante. La funci´on fue dise˜nada de tal forma para aliviar al programador el tener que escribir la adquisici´on de locks en un determinado orden con el fin evitar deadlocks. 1 # include <mutex> 2 std : : mutex mutex1 , mutex2 ; 3 void task1 ( ) { 4 std : : lock ( mutex1 , mutex2 ) ; 5 / / c r i t i c a l section 6 mutex1 . unlock ( ) ; 7 mutex2 . unlock ( ) ; 8 } 1 2 3 void task2 ( ) { 4 std : : lock ( mutex2 , mutex1 ) ; 5 / / c r i t i c a l section 6 mutex1 . unlock ( ) ; 7 mutex2 . unlock ( ) ; 8 } Sebasti´an Vizcay June 16, 2015 46/79
  • 47. Taller de Programaci´on Paralela Mutex Funciones adicionales La funci´on try lock funciona de forma similar a la funci´on lock pero invocar´a al m´etodo try lock de todos los mutex que se le indiquen dentro de la lista de par´ametros. Try lock retornar´a -1 en caso en que obtenga todos los locks satisfatoriamente o un n´umero entero indicando el ´ındice del primer mutex del cual no logr´o adquirir su lock. Sebasti´an Vizcay June 16, 2015 47/79
  • 48. Taller de Programaci´on Paralela Mutex Funciones adicionales: call once y once flag Si tenemos una funci´on que ser´a ejecutada por m´ultiples hebras y deseamos que cierta parte de la funci´on sea solo ejecutada por tan solo una hebra, podemos utilizar la funci´on call once para especificar las l´ıneas de c´odigo que deben ejecutarse solo una vez. La funci´on call once recibe como par´ametro una funci´on, un objeto funcional, un lambda o cualquer otro objeto que se comporte como funci´on para indicar el c´odigo a ejecutar. Call once necesita verificar una variable del tipo once flag para ver si el c´odigo ya fue o no ejecutado por alguna otra hebra. Sebasti´an Vizcay June 16, 2015 48/79
  • 49. Taller de Programaci´on Paralela Mutex Uso de call once 1 # include <mutex> 2 3 std : : once flag f l a g ; 4 5 void task ( ) { 6 std : : call once ( flag , [ ] ( ) { 7 std : : cout << ” p r i n t j u s t once ” << std : : endl ; 8 }); 9 std : : cout << ” p r i n t every single time ” << std : : endl ; 10 } Sebasti´an Vizcay June 16, 2015 49/79
  • 50. Taller de Programaci´on Paralela Condition variable Caracter´ısticas principales #include <condition variable> Las variables de condici´on manejan una lista de hebras que se encuentran a la espera de que otra hebra notifique alg´un evento. Toda hebra que necesita esperar por alguna variable de condici´on, DEBE haber adquirido previamente el lock. El lock es liberado una vez que la hebra comienza a esperar en la variable de condici´on. El lock es obtenido nuevamente una vez que la hebra es se˜nalizada para continuar. Sebasti´an Vizcay June 16, 2015 50/79
  • 51. Taller de Programaci´on Paralela Condition variable Caracter´ısticas principales El mutex DEBE ser manejado por el wrapper unique lock. Si se desea utilizar otro tipo de wrapper, se debe utilizar una variable de condici´on del tipo condition variable any. Sebasti´an Vizcay June 16, 2015 51/79
  • 52. Taller de Programaci´on Paralela Condition variable Caracter´ısticas principales Los m´etodos principales son wait, notify one y notify all. El m´etodo wait bloquea a la hebra en espera del evento en particular. El m´etodo notify one despertar´a a solo una hebra que se encuentre en la cola de hebras esperando por el evento que representa la variable de condici´on. En caso en que no haya ninguna hebra esperando, no sucede nada en particular. El m´etodo notify all despertar´a a todas las hebras esperando por tal evento. Notar que las hebras despertadas a´un tendr´an que tomar el lock nuevamente, por lo que la ejecuci´on de ellas y su acceso a la secci´on critica sigue siendo serializado. De igual forma a notify one, si no existe ninguna hebra en la cola de espera, no suceder´a nada especial. Sebasti´an Vizcay June 16, 2015 52/79
  • 53. Taller de Programaci´on Paralela Condition variable Caracter´ısticas principales El m´etodo wait toma como primer par´ametro obligatorio el mutex del cual debe liberar el lock antes de bloquearse. El segundo parametro es opcional y corresponde a un predicado (algo que puede evaluarse a true o false) que indicar´a si la hebra debe efectivamente despertar o seguir bloqueada aun cuando se haya despertado. El especificar un predicado es equivalente a envolver la llamada a wait con un while verificando por la negaci´on del predicado. Sebasti´an Vizcay June 16, 2015 53/79
  • 54. Taller de Programaci´on Paralela Condition variable Especificando un predicado 1 std : : mutex mutex ; 2 std : : unique lock<std : : mutex> lock ( mutex ) ; 3 std : : c o n d i t i o n v a r i a b l e insertOne ; 4 while ( counter == 0) { 5 insertOne . wait ( lock ) ; 6 } 1 std : : mutex mutex ; 2 std : : unique lock<std : : mutex> lock ( mutex ) ; 3 std : : c o n d i t i o n v a r i a b l e insertOne ; 4 insertOne . wait ( lock , [ counter ] ( ) −> bool { 5 return counter != 0}); Sebasti´an Vizcay June 16, 2015 54/79
  • 55. Taller de Programaci´on Paralela Condition variable Spurious Wakes Cuando no se especifica un predicado en el segundo par´ametro del wait, hay que tener cuidado de envolver la llamada a wait con un while y no con una simple instrucci´on if. Una hebra puede despertar aun cuando no se haya realizado ninguna se˜nalizaci´on a trav´es de alg´un notify. Esto es conocido como spurious wakes (despertar err´oneo) y no pueden ser predichos. Spurious wakes generalmente ocurren cuando la biblioteca de hebras no puede asegurar que la hebra dormida no se perder´a de alguna notificaci´on, por lo que decide despertarla para evitar el riesgo. Al utilizar un while o un predicado, nos aseguramos que la hebra despierta solamente cuando corresponde. Sebasti´an Vizcay June 16, 2015 55/79
  • 56. Taller de Programaci´on Paralela Condition variable Ejemplo completo de variables de condici´on 1 class Buffer { 2 public : 3 Buffer ( unsigned size = 0 ) ; 4 ˜ Buffer ( ) ; 5 void i n s e r t ( i n t item ) ; 6 i n t remove ( ) ; 7 private : 8 unsigned size ; 9 unsigned counter ; 10 i n t ∗items ; 11 std : : c o n d i t i o n a l v a r i a b l e removeOne , insertOne ; 12 std : : mutex mutex ; 13 }; Sebasti´an Vizcay June 16, 2015 56/79
  • 57. Taller de Programaci´on Paralela Condition variable Ejemplo completo de variables de condici´on 1 # include ” buffer . hpp ” 2 Buffer : : Buffer ( unsigned size ) : size ( size ) , 3 counter (0) , items (new i n t [ size ] ) {} 4 5 Buffer : : ˜ Buffer ( ) { 6 delete [ ] items ; 7 } Sebasti´an Vizcay June 16, 2015 57/79
  • 58. Taller de Programaci´on Paralela Condition variable Ejemplo completo de variables de condici´on 1 void Buffer : : i n s e r t ( i n t item ) { 2 std : : unique lock<std : : mutex> lock ( mutex ) ; 3 removeOne . wait ( lock , [ t h i s ] ( ) −> bool { 4 return counter != size ; } ) ; 5 items [ counter ] = item ; 6 counter ++; 7 8 insertOne . notify one ( ) ; 9 } Sebasti´an Vizcay June 16, 2015 58/79
  • 59. Taller de Programaci´on Paralela Condition variable Ejemplo completo de variables de condici´on 1 void Buffer : : remove ( ) { 2 std : : unique lock<std : : mutex> lock ( mutex ) ; 3 while ( counter == 0) { 4 insertOne . wait ( lock ) ; 5 } 6 counter−−; 7 i n t item = items [ counter ] ; 8 9 removeOne . notify one ( ) ; 10 11 return item ; 12 } Sebasti´an Vizcay June 16, 2015 59/79
  • 60. Taller de Programaci´on Paralela Condition variable Ejemplo completo de variables de condici´on 1 # include <thread> 2 # include ” buffer . hpp ” 3 4 void consumer ( i n t tid , Buffer & buffer ) { 5 i n t value = buffer . remove ( ) ; 6 std : : cout << ” thread=” << t i d ; 7 std : : cout << ” took the value ” ; 8 std : : cout << value << std : : endl ; 9 } 10 11 void producer ( i n t tid , Buffer & buffer ) { 12 buffer . i n s e r t ( t i d ) ; 13 } Sebasti´an Vizcay June 16, 2015 60/79
  • 61. Taller de Programaci´on Paralela Condition variable Ejemplo completo de variables de condici´on 1 i n t main ( i n t argc , char ∗argv [ ] ) { 2 Buffer buffer ( 5 ) ; 3 std : : thread consumers [1000] , producers [1000]; 4 5 f o r ( unsigned i = 0; i < 1000; i ++) { 6 consumers [ i ] = std : : thread ( consumer , i , std : : r e f ( buffer ) ) ; 7 producers [ i ] = std : : thread ( producer , i , std : : r e f ( buffer ) ) ; 8 } 9 f o r ( unsigned i = 0; i < 1000; i ++) { 10 consumers [ i ] . j o i n ( ) ; 11 producers [ i ] . j o i n ( ) ; 12 } 13 return 0; 14 } Sebasti´an Vizcay June 16, 2015 61/79
  • 62. Taller de Programaci´on Paralela Atomic Caracter´ısticas principales #include <atomic>. Atomic permite la implementaci´on de algoritmos libres de locks. Operaciones at´omicas presentan mejor performance que su equivalente utilizando locks. Uno debe especificar el tipo de variable que ser´a tratada de forma at´omica (thread-safe). Va a depender de la implementaci´on el mecanismo utilizado para asegurar que la operaci´on sea thread-safe, pudiendo incluso llegar a utilizarse locks. Generalmente para tipos de datos b´asicos, las implementaciones quedan libres de locks. Sebasti´an Vizcay June 16, 2015 62/79
  • 63. Taller de Programaci´on Paralela Atomic Caracter´ısticas principales Los m´etodos principales son load y store. El m´etodo load funciona como los m´etodos get y simplemente retorna el valor actual. El m´etodo store setea un nuevo valor a la variable del tipo atomic. Existe otro m´etodo llamado exchange, el cual setea un nuevo valor a la variable at´omica y al mismo tiempo retorna el valor antiguo. Sebasti´an Vizcay June 16, 2015 63/79
  • 64. Taller de Programaci´on Paralela Atomic Ejemplo de atomic 1 # include <atomic> 2 i n t main ( i n t argc , char ∗argv [ ] ) { 3 i n t i n i t i a l V a l u e = 5; 4 std : : atomic<int> atomic ( i n i t i a l V a l u e ) ; 5 i n t newValue = 10; 6 atomic . store ( newValue ) ; 7 i n t lastValue = atomic . load ( ) ; 8 9 return 0; 10 } Sebasti´an Vizcay June 16, 2015 64/79
  • 65. Taller de Programaci´on Paralela Atomic Caracter´ısticas principales Los m´etodos load y store permiten adem´as especificar el modelo de memoria a utilizar (secuencialmente consistente es el modelo por defecto). Los modelos de memoria describen si los accesos a memoria pueden ser optimizados ya sea por el compilador o por el procesador. Si el modelo es relajado, se permite que las operaciones sean reordenadas o combinadas con el fin de mejorar el performance. El modelo m´as estricto es el secuencialmente consistente, el cual es el por defecto. Sebasti´an Vizcay June 16, 2015 65/79
  • 66. Taller de Programaci´on Paralela Atomic Ejemplo del m´etodo exchange 1 # include <atomic> 2 std : : atomic<bool> winner ( false ) ; 3 4 void race ( ) { 5 i f ( ! winner . exchange ( true ) ) { 6 std : : cout << ” winner id = ” ; 7 std : : cout << std : : t h i s t h r e a d : : g e t i d ( ) << std : : endl ; 8 } 9 } Sebasti´an Vizcay June 16, 2015 66/79
  • 67. Taller de Programaci´on Paralela Atomic Ejemplo del m´etodo exchange 1 # include <thread> 2 3 i n t main ( i n t argc , char ∗argv [ ] ) { 4 std : : thread threads [ 1 0 ] ; 5 6 f o r ( unsigned i = 0; i < 10; i ++) { 7 threads [ i ] = std : : thread ( race ) ; 8 } 9 10 f o r ( unsigned i = 0; i < 10; i ++) { 11 threads [ i ] . j o i n ( ) ; 12 } 13 14 return 0; 15 } Sebasti´an Vizcay June 16, 2015 67/79
  • 68. Taller de Programaci´on Paralela Future Comunicaci´on as´ıncrona con Future #include <future>. La funci´on async nos permite lanzar la ejecuci´on de una hebra sin que necesariamente comience su ejecuci´on inmediatamente. Si la funci´on que lanzamos as´ıncronamente retornar alg´un valor, podemos consultar por el valor retornado almacen´andolo en una variable del tipo future. La clase future es una clase template (de igual forma que atomic), en donde se debe especificar el tipo de dato que ser´a utilizado en el template. El tipo de dato tiene que corresponderse con el tipo de dato retornado por la funci´on lanzada as´ıncronamente. Sebasti´an Vizcay June 16, 2015 68/79
  • 69. Taller de Programaci´on Paralela Future Comunicaci´on as´ıncrona con Future En general se puede ver el header future como un conjunto de utilidades que permiten acceso as´ıncrono a valores que ser´an seteados por proveedores corriendo en otras hebras de ejecuci´on. El m´etodo get es el m´etodo principal de los objetos del tipo future. El m´etodo get es el que obliga a que el valor sea finalmente calculado/seteado en caso en que todav´ıa no lo haya sido. En el caso en que el valor todav´ıa no se encuentre disponible, la hebra ejecutando el m´etodo get se bloquear´a hasta que el valor se encuentre disponible. La hebra calculando el valor puede setear una excepci´on en el valor a retornar, lanz´andose efectivamente al momento en que se realiza la llamada a get. Sebasti´an Vizcay June 16, 2015 69/79
  • 70. Taller de Programaci´on Paralela Future Ejemplo de future 1 # include <future> 2 3 i n t add ( i n t a , i n t b ) { 4 return a+b ; 5 } 6 7 i n t main ( i n t argc , char ∗argv [ ] ) { 8 std : : future<int> r e s u l t ( std : : async ( add , 2 , 4) ) ; 9 10 std : : cout << r e s u l t . get ( ) << std : : endl ; 11 12 return 0; 13 } Sebasti´an Vizcay June 16, 2015 70/79
  • 71. Taller de Programaci´on Paralela Future Proveedores para future La funci´on async es la m´as f´acil de utilizar para proveer de valores a las variables del tipo future. Adem´as de la funci´on async, se cuenta con los objetos de las clases promise y packaged task. La clase promise es una clase template que permite proveer de valores o de excepciones a variables del tipo future. Los m´etodos principales de un objeto promise son get future, set value y set exception. Sebasti´an Vizcay June 16, 2015 71/79
  • 72. Taller de Programaci´on Paralela Future Proveedores para future - promise El m´etodo get future es la forma en la que se vincula el future con el promise. Se debe invocar al m´etodo get future cuando se est´a construyendo/incializando el objeto del tipo future. Posterior a esta invocaci´on, el objeto del tipo promise y future poseer´an un estado compartido. Solo puede retornarse un future por promise. Una vez que se ha generado el v´ınculo, se espera que en alg´un momento el promise setee el valor esperado por el future, o que simplemente setee alguna excepci´on para que sea lanzada por el future al intentar recuperar el valor con el m´etodo get. Sebasti´an Vizcay June 16, 2015 72/79
  • 73. Taller de Programaci´on Paralela Future Proveedores para future - promise Si se llegase a ejecutar el destructor de la variable de tipo promise sin que ´esta haya alcanzado a setear alg´un valor o excepci´on, el estado de la informaci´on pasar´a a estar como disponible y la invocaci´on del m´etodo get del future retornar´a. En el momento en que retorne get, se lanzar´a una excepci´on del tipo future error. Cuando en alguna hebra de ejecuci´on se invoca a una de los m´etodos set value o set exception, el estado cambia a disponible y la hebra bloqueada en la invocaci´on a get retorna. Sebasti´an Vizcay June 16, 2015 73/79
  • 74. Taller de Programaci´on Paralela Future Ejemplo de future y promise 1 # include <future> 2 # include <thread> 3 # include <exception> 4 5 void p r i n t ( std : : future<int> & future ) { 6 t r y { 7 std : : cout << future . get ( ) << std : : endl ; 8 } catch ( std : : exception & e ) { 9 std : : cerr << e . what ( ) << std : : endl ; 10 } 11 } Sebasti´an Vizcay June 16, 2015 74/79
  • 75. Taller de Programaci´on Paralela Future Ejemplo de future y promise 1 i n t main ( i n t argc , char ∗argv [ ] ) { 2 std : : promise<int> promise ; 3 std : : future<int> future ( promise . g e t f u t u r e ( ) ) ; 4 std : : thread thread ( p r i nt , std : : r e f ( future ) ) ; 5 promise . set value ( 1 5 ) ; 6 7 thread . j o i n ( ) ; 8 9 return 0; 10 } Sebasti´an Vizcay June 16, 2015 75/79
  • 76. Taller de Programaci´on Paralela Future Proveedores para future - packaged task La clase packaged task funciona de forma similar al promise pero se diferencian en que la primera envuelve a un objeto llamable (una funci´on, una expresi´on lambda, un functor etc.). El valor retornado por el objeto funcional es lo que se setea como valor a almacenar en el future, es decir, ya no es necesario especificar el valor a trav´es de alguna llamada a set value como se hac´ıa en los objetos promise. La clase packaged task es una clase template y dentro de los par´ametros del template se debe especificar el tipo de retorno de la funci´on y los tipos de variables de los par´ametros. Sebasti´an Vizcay June 16, 2015 76/79
  • 77. Taller de Programaci´on Paralela Future Ejemplo de future y packaged task 1 i n t add ( i n t a , i n t b ) { 2 return a+b ; 3 } 4 5 i n t main ( i n t argc , char ∗argv [ ] ) { 6 std : : packaged task<i n t ( int , i n t )> task ( add ) ; 7 std : : future<int> future ( task . g e t f u t u r e ( ) ) ; 8 std : : thread thread ( std : : move( task ) , 3 , 4 ) ; 9 std : : cout << future . get ( ) << std : : endl ; 10 thread . j o i n ( ) ; 11 return 0; 12 } Sebasti´an Vizcay June 16, 2015 77/79
  • 78. Taller de Programaci´on Paralela Compilaci´on C++11 utilza hebras provistas por la plataforma. pthreads Unix. win32 threads Windows Consultar por la biblioteca de hebras utilizadas por el compilador. $ g++ -v (buscar por la l´ınea Thread model). Compilar con flag -std=c++11 o -std=c++0x, y enlazar con pthreads. g++ -c -Wall -std=c++11 -o main.o main.cpp g++ -o program.exe main.o -pthreads En caso de error al enlazar con pthread. g++ -o program.exe main.o -pthreads -Wl,–no-as-needed Sebasti´an Vizcay June 16, 2015 78/79