#ifndef MUTEX_VITO_H
#define MUTEX_VITO_H
#ifdef _WIN32
#include<windows.h>
#else
#include <pthread.h>
#endif
class MutexVito
{
public:
MutexVito();
~MutexVito();
void lock() const;
void unlock() const;
bool tryLock() const;
private:
void init();
MutexVito(const MutexVito&);
void operator=(const MutexVito&);
#ifdef _WIN32
mutable CRITICAL_SECTION _mutex;
#else
mutable pthread_mutex_t _mutex;
#endif
};
#endif
#include "MutexVito.h"
#include<assert.h>
MutexVito::MutexVito()
{
init();
}
void MutexVito::init()
{
#ifdef _WIN32
InitializeCriticalSection(&_mutex);
#else
int rc;
pthread_mutexattr_t attr;
rc = pthread_mutexattr_init(&attr);
assert(rc == 0);
if (rc != 0)
{
pthread_mutexattr_destroy(&attr);
}
#ifndef NDEBUG
#if defined(__linux) && !defined(__USE_UNIX98)
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
#else
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
assert(rc == 0);
if (rc != 0)
{
pthread_mutexattr_destroy(&attr);
}
#endif
#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0
if (PrioInherit == protocol)
{
rc = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
if (rc != 0)
{
pthread_mutexattr_destroy(&attr);
}
}
#endif
rc = pthread_mutex_init(&_mutex, &attr);
assert(rc == 0);
if (rc != 0)
{
pthread_mutexattr_destroy(&attr);
}
rc = pthread_mutexattr_destroy(&attr);
assert(rc == 0);
#endif
}
MutexVito::~MutexVito()
{
#ifdef _WIN32
DeleteCriticalSection(&_mutex);
#else
int rc = 0;
rc = pthread_mutex_destroy(&_mutex);
assert(rc == 0);
#endif // _WIN32
}
void MutexVito::lock() const
{
#ifdef _WIN32
EnterCriticalSection(&_mutex);
#else
int rc = pthread_mutex_lock(&_mutex);
assert(rc == 0);
#endif
}
void MutexVito::unlock() const
{
#ifdef _WIN32
LeaveCriticalSection(&_mutex);
#else
int rc = pthread_mutex_unlock(&_mutex);
assert(rc == 0);
#endif
}
bool MutexVito::tryLock() const
{
#ifdef _WIN32
if (!TryEnterCriticalSection(&_mutex))
{
return false;
}
if (_mutex.RecursionCount > 1)
{
LeaveCriticalSection(&_mutex);
}
return true;
#else
int rc = pthread_mutex_trylock(&_mutex);
assert(rc == 0);
return (rc == 0);
#endif
}
#include "MutexVito.h"
#include<iostream>
#include<thread>
MutexVito mutex;
void print_block(int n, char c) {
// critical section (exclusive access to std::cout signaled by locking mtx):
//mutex.lock();
for (int i = 0; i<n; ++i) { std::cout << c; }
std::cout << '\n';
//mutex.unlock();
}
void test_mutex()
{
std::thread th1(print_block, 10000, '*');
std::thread th2(print_block, 10000, '$');
th1.join();
th2.join();
}
int main()
{
test_mutex();
return 0;
}