Linux下C/C++ 多线程同步

#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/*

你可能感兴趣的:(linux)