#include <pthread.h>
#include "PosixMutexLock.hpp"
#ifndef POSIX_SYNC
#define POSIX_SYNC
class PosixSync
{
private:
protected:
PosixMutexLock *lock;
pthread_cond_t block;
public:
PosixSync();
void wait();
void notify();
};
#endif
===========================================
#include <stdio.h>
#include "PosixSync.hpp"
PosixSync::PosixSync()
{
lock = new PosixMutexLock();
int error = pthread_cond_init (&block, NULL);
if (error)
{
printf("condition variable init fail, fail to call pthread_cond_init, error %d\n", error);
}
}
void PosixSync::wait()
{
int error = pthread_cond_wait(&block, lock->getMutex());
if (error)
{
printf("condition variable wait fail, fail to call pthread_cond_wait, error %d\n", error);
}
}
void PosixSync::notify()
{
int error = pthread_cond_signal(&block);
if (error)
{
printf("condition variable signal fail, fail to call pthread_cond_signal, error %d\n", error);
}
}
=========================================================
#include <pthread.h>
#include "../Lock.hpp"
#ifndef POSIX_MUTEX_LOCK
#define POSIX_MUTEX_LOCK
class PosixMutexLock : public Lock
{
private:
pthread_mutex_t mutex;
public:
PosixMutexLock();
PosixMutexLock(const char* name);
~PosixMutexLock();
void lock();
void lock(pthread_mutex_t* mutex);
void unlock();
void unlock(pthread_mutex_t* mutex);
pthread_mutex_t* getMutex();
};
#endif
=====================================================
#include <stdio.h>
#include <pthread.h>
#include "PosixMutexLock.hpp"
PosixMutexLock::PosixMutexLock()
{
int error = pthread_mutex_init(&mutex, NULL);
if (error)
{
printf("mutex init fail, fail to call pthread_mutex_init, error %d\n", error);
}
}
PosixMutexLock::PosixMutexLock(const char* name)
{
int error = pthread_mutex_init(&mutex, NULL);
if (error)
{
printf("mutex init fail, fail to call pthread_mutex_init, error %d\n", error);
}
}
PosixMutexLock::~PosixMutexLock()
{
int error = pthread_mutex_destroy(&mutex);
if (error)
{
printf("mutex destroy fail, fail to call pthread_mutex_destroy, error %d\n", error);
}
}
void PosixMutexLock::lock()
{
lock(&mutex);
}
void PosixMutexLock::lock(pthread_mutex_t* mutex)
{
int error = pthread_mutex_lock(mutex);
if (error)
{
printf("lock fail, fail to call pthread_mutex_lock, error %d\n", error);
}
}
void PosixMutexLock::unlock()
{
unlock(&mutex);
}
void PosixMutexLock::unlock(pthread_mutex_t* mutex)
{
int error = pthread_mutex_unlock(mutex);
if (error)
{
printf("unlock fail, fail to call pthread_mutex_lock, error %d\n", error);
}
}
pthread_mutex_t* PosixMutexLock::getMutex()
{
return &mutex;
}
==================================================
#ifndef __LOCK
#define __LOCK
class Lock
{
public:
virtual void lock() = 0;
virtual void unlock() = 0;
};
#endif
=======================================
/*
*
*
* @author ada
* @version 1.0
* @since 1.0
*/
#include "../Runnable.hpp"
#define GLOBAL_START_ROUTINE
#if ! defined POSIX_THREAD
#define POSIX_THREAD
// On linux and linux like system, the start routine function defined
//
// void *(*start_routine)(void*)
//
// And on windows system,
//
// The LPTHREAD_START_ROUTINE type defines a pointer to this callback function.
// ThreadProc is a placeholder for the application-defined function name.
//
// typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE) (
// [in] LPVOID lpThreadParameter
// );
//
// Function prototype:
//
// DWORD WINAPI ThreadProc(
// _In_ LPVOID lpParameter
// );
//
#if defined GLOBAL_START_ROUTINE
#ifdef _WIN32
DWORD __stdcall execute(LPVOID args);
#else
void* execute(void *args);
#endif
#endif
#ifndef _WIN32
typedef void* (*PTHREAD_START_ROUTINE)(void *args);
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
#endif
class PosixThread : public Runnable
{
public:
#if ! defined GLOBAL_START_ROUTINE
static void* execute(void *args);
#endif
void start();
virtual void run();
};
#endif
=================================================
/*
*
*
* @author ada
* @version 1.0
* @since 1.0
*/
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "PosixThread.hpp"
#if ! defined GLOBAL_START_ROUTINE
void* PosixThread::execute(void *args)
{
PosixThread* t = (PosixThread *) args;
t->run();
return 0;
}
#else
void* execute(void *args)
{
PosixThread* t = (PosixThread *) args;
t->run();
return 0;
}
#endif
void PosixThread::start()
{
pthread_t pthread;
#ifndef GLOBAL_START_ROUTINE
LPTHREAD_START_ROUTINE startRoutine = (LPTHREAD_START_ROUTINE) PosixThread::execute;
printf("GLOBAL_START_ROUTINE not defined, do not using global thread start routine\n");
#else
LPTHREAD_START_ROUTINE startRoutine = (LPTHREAD_START_ROUTINE) execute;
printf("GLOBAL_START_ROUTINE defined, using global thread start routine\n");
#endif
int error = pthread_create(&pthread,
NULL,
startRoutine,
(void *) this);
if (error)
{
printf("Thread start fail: fail to call pthread_create, error %d\n", error);
}
}
void PosixThread::run()
{
printf("PosixThread::run()\n");
}
=============================================
#include <stdio.h>
#include "../posix/PosixThread.hpp"
#include "TestPosixMutexLockMessageDestination.hpp"
#ifndef TEST_POSIX_MUTEX_LOCK_MESSAGE_CONSUMER
#define TEST_POSIX_MUTEX_LOCK_MESSAGE_CONSUMER
class TestPosixMutexLockMessageConsumer : public PosixThread
{
private:
TestPosixMutexLockMessageDestination *destination;
public:
TestPosixMutexLockMessageConsumer();
void registerConsumer(TestPosixMutexLockMessageDestination *destination);
void run();
};
#endif
===================================================
#include <unistd.h>
#include "TestPosixMutexLockMessageConsumer.hpp"
TestPosixMutexLockMessageConsumer::TestPosixMutexLockMessageConsumer()
{
this->destination = NULL;
}
void TestPosixMutexLockMessageConsumer::registerConsumer(TestPosixMutexLockMessageDestination *destination)
{
this->destination = destination;
}
void TestPosixMutexLockMessageConsumer::run()
{
while (1)
{
if (destination != NULL)
{
this->destination->reduce();
}
//sleep(1);
}
}
======================================================
#include <stdio.h>
#include "../posix/PosixThread.hpp"
#include "TestPosixMutexLockMessageDestination.hpp"
#ifndef TEST_POSIX_MUTEX_LOCK_MESSAGE_PRODUCER
#define TEST_POSIX_MUTEX_LOCK_MESSAGE_PRODUCER
class TestPosixMutexLockMessageProducer : public PosixThread
{
private:
TestPosixMutexLockMessageDestination *destination;
public:
TestPosixMutexLockMessageProducer();
void registerProducer(TestPosixMutexLockMessageDestination *destination);
void run();
};
#endif
=========================================================
#include <unistd.h>
#include "TestPosixMutexLockMessageProducer.hpp"
TestPosixMutexLockMessageProducer::TestPosixMutexLockMessageProducer()
{
this->destination = NULL;
}
void TestPosixMutexLockMessageProducer::registerProducer(TestPosixMutexLockMessageDestination *destination)
{
this->destination = destination;
}
void TestPosixMutexLockMessageProducer::run()
{
while (1)
{
if (destination != NULL)
{
destination->add();
}
sleep(5);
}
}
===========================================================
#include <stdio.h>
#include "../posix/PosixSync.hpp"
#include "../posix/PosixMutexLock.hpp"
#ifndef TEST_POSIX_MUTEX_LOCK_MESSAGE_DESTINATION
#define TEST_POSIX_MUTEX_LOCK_MESSAGE_DESTINATION
class TestPosixMutexLockMessageDestination : public PosixSync
{
private:
int i;
public:
TestPosixMutexLockMessageDestination();
void add();
void reduce();
};
#endif
=============================================
#include "TestPosixMutexLockMessageDestination.hpp"
TestPosixMutexLockMessageDestination::TestPosixMutexLockMessageDestination()
{
i = 0;
}
void TestPosixMutexLockMessageDestination::add()
{
lock->lock();
i++;
printf("[Producer] message %d\n", this->i);
if (i > 0)
{
notify();
}
lock->unlock();
}
void TestPosixMutexLockMessageDestination::reduce()
{
lock->lock();
if (i <= 0)
{
wait();
}
i--;
printf("[Consumer] message %d\n", i);
lock->unlock();
}
====================================================
#include "TestPosixMutexLockMessageDestination.hpp"
#include "TestPosixMutexLockMessageProducer.hpp"
#include "TestPosixMutexLockMessageConsumer.hpp"
int main()
{
TestPosixMutexLockMessageDestination *destination = new TestPosixMutexLockMessageDestination();
TestPosixMutexLockMessageProducer *producer = new TestPosixMutexLockMessageProducer();
producer->registerProducer(destination);
producer->start();
TestPosixMutexLockMessageConsumer *consumer = new TestPosixMutexLockMessageConsumer();
consumer->registerConsumer(destination);
consumer->start();
pthread_exit(NULL);
return 0;
}
====================================================
OUTPUT = ../Debug/
Observable_objects = $(OUTPUT)*.o
Release: clean
g++ -c ../posix/*.cpp
mv ./*.o ../Debug
g++ -c TestPosixMutexLockMessageConsumer.cpp -o ../Debug/TestPosixMutexLockMessageConsumer.o
g++ -c TestPosixMutexLockMessageProducer.cpp -o ../Debug/TestPosixMutexLockMessageProducer.o
g++ -c TestPosixMutexLockMessageDestination.cpp -o ../Debug/TestPosixMutexLockMessageDestination.o
g++ -c PosixMutexLockTest.cpp -o ../Debug/PosixMutexLockTest.o
g++ $(Observable_objects) -o $(OUTPUT)PosixMutexLockTest
clean:
rm -Rf ./*.bak
rm -Rf ./*.o
rm -Rf ./*.exe
rm -Rf ../Debug/*