Sunteți pe pagina 1din 5

Introduccin al multiprocesamiento en C++ IV: sincronizacin con Mutex

Despus de un breve descanso veraniego, hoy vamos a continuar con la serie introduccin al multiprocesamiento en C++. En esta cuarta parte vamos a crear un wrapper alrededor de algunos mecanismos de sincronizacin. Ms especficamente vamos a crear una clase alrededor de la primitiva de sincronizacin mutex que ya vimos en el primer artculo de la serie. Para nuestro wrapper sencillo alrededor de los threads vamos a utilizar solo mutexes por que creo que es lo nico que vamos a necesitar.

GThreads con Mutex


Windows tiene una estructura propia llamada mutex pero no vamos a hacer uso de ellos en nuestra clase. Los objetos mutex de Windows pueden ser usados entre procesos y son bastante pesados. Para nuestro cometido no vamos a necesitar la funcionalidad adicional que ofrece ese tipo de objeto as que vamos a implementar una clase de mutex ligera cuyos objetos puedan ser usados entre diferentes threads pero no entre procesos.

En Windows vamos a utilizar el objeto ligero critical section que es precisamente un mutex que cubre perfectamente nuestras necesidades.

El Mutex
Vamos a crear un nuevo archivo llamado gmutex.h (Genbeta Mutex) y vamos a escribir una sencilla clase que sirva como wrapper alrededor de las estructuras pthread_mutex_t en Unix y CRITICAL_SECTION en Windows. Para ello vamos a hacer uso como siempre de la compilacin condicional a la que ya estamos acostumbrados, vamos a escribir un prototipo de nuestra clase:
class GMutex { protected: // Tipos de mutex #ifdef WIN32 CRITICAL_SECTION m_mutex; #else pthread_mutex_t m_mutex; #endif };

El Constructor
En ambas APIs es necesario que el objeto mutex sea iniciado antes de poder utilizarlo, as que vamos a hacerlo en el constructor:
GMutex() { #ifdef WIN32 InitializeCriticalSection( &m_mutex ); #else phtread_mutex_init( &m_mutex, 0 ); #endif }

El segundo argumento en la funcin para Unix es supustamente un puntero a una estructura de configuracin para el mutex pero no es muy necesario. Al pasar el valor 0 los atributos por defecto son aplicados.

Destructor
Ambas APIs requieren de la destruccin del mutex cuando hemos terminado de usarlos. Lo lgico es aadirlo al destructor de la clase:
~GMutex() {

#ifdef WIN32 DeleteCriticalSection( &m_mutex ); #else pthread_mutex_destroy( &m_mutex ); #endif }

Adquirir el Mutex
Adquirir un mutex es una tarea sencilla con ambas APIs:
inline void Lock() { #ifdef WIN32 EnterCriticalSection( &m_mutex ); #else pthread_mutex_lock( &m_mutex ); #endif }

Liberar el Mutex
Liberarlo es igual de sencillo:
inline void Unlock() { #ifdef WIN32 LeaveCriticalSection( &m_mutex ); #else pthread_mutex_unlock( &m_mutex ); #endif }

Cdigo completo
El cdigo completo de la clase es el siguiente:
#ifndef _GMutex_h_ #define _GMutex_h_ #ifdef WIN32 #include <windows.h> #else #include <pthreads.h> #endif namespace ThreadLib {

class GMutex { public: GMutex() { #ifdef WIN32 InitializeCriticalSection( &m_mutex ); #else pthread_mutex_init( &m_mutex ); #endif } ~GMutex() { #ifdef WIN32 DeleteCriticalSection( &m_mutex ); #else pthread_mutex_destroy( &m_mutex ); #endif } inline void Lock() { #ifdef WIN32 EnterCriticalSection( &m_mutex ); #else pthread_mutex_lock( &m_mutex ); #endif } inline void Unlock() { #ifdef WIN32 LeaveCriticalSection( &m_mutex ); #else pthread_mutex_unlock( &m_mutex ); #endif } protected: #ifdef WIN32 CRITICAL_SECTION m_mutex; #else pthread_mutex_t m_mutex; #endif } } #endif // _GMutex_h_

Como podis comprobar, nos ha quedado una clase muy sencilla. En el prximo artculo veremos como utilizar esta librera en una demo sencilla.

En Genbeta Dev | Introduccin al multiprocesamiento en C++

S-ar putea să vă placă și