封装了linux和win32的基本线程操作:包括创建线程,等待线程完成,kill线程等等。
ThreadException.h
Code
#ifndef THREADEXCEPTION_H
#define THREADEXCEPTION_H
#include <exception>
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#ifdef WIN32 // windows95 and above
#include <windows.h>
#else // linux
#include <pthread.h>
#endif
namespace ThreadLib
{
enum Error
{
Unspecified, // unspecified error
InitFailure, // thread library not initialized
CreationFailure // thread cannot be created
};
class Exception : public std::exception
{
public:
// ====================================================================
// Description: set the error code of the exception, with a default of
// Unspecified.
// ====================================================================
Exception( Error p_error = Unspecified )
{
m_error = p_error;
}
// ====================================================================
// Description: Gets the error code of the exception
// ====================================================================
Error GetError() const
{
return m_error;
}
protected:
Error m_error;
};
}
#endif
#ifndef THREADEXCEPTION_H
#define THREADEXCEPTION_H
#include <exception>
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#ifdef WIN32 // windows95 and above
#include <windows.h>
#else // linux
#include <pthread.h>
#endif
namespace ThreadLib
{
enum Error
{
Unspecified, // unspecified error
InitFailure, // thread library not initialized
CreationFailure // thread cannot be created
};
class Exception : public std::exception
{
public:
// ====================================================================
// Description: set the error code of the exception, with a default of
// Unspecified.
// ====================================================================
Exception( Error p_error = Unspecified )
{
m_error = p_error;
}
// ====================================================================
// Description: Gets the error code of the exception
// ====================================================================
Error GetError() const
{
return m_error;
}
protected:
Error m_error;
};
}
#endif
ThreadLib.h
Code
#ifndef THREADLIB_H
#define THREADLIB_H
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#include "ThreadLibFunctions.h"
#include "ThreadException.h"
#include "ThreadLibMutex.h"
#endif
#ifndef THREADLIB_H
#define THREADLIB_H
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#include "ThreadLibFunctions.h"
#include "ThreadException.h"
#include "ThreadLibMutex.h"
#endif
ThreadLibFunctions.cpp
Code
#include "ThreadLib.h"
namespace ThreadLib
{
// ========================================================================
// This is the handle-map global, only used in Win32.
// ========================================================================
#ifdef WIN32
std::map< DWORD, HANDLE > g_handlemap;
#endif
// ========================================================================
// Description: This is a "dummy" thread function that will be used to
// transparently translate function pointers to whatever
// system the user is currently compiling on.
// ========================================================================
#ifdef WIN32
DWORD WINAPI DummyRun( void* p_data )
#else
void* DummyRun( void* p_data )
#endif
{
// convert the dummy data
DummyData* data = (DummyData*)p_data;
// run the function with the given data
data->m_func( data->m_data );
// now delete the data
delete data;
// and return 0.
return 0;
}
} // end namespace ThreadLib
#include "ThreadLib.h"
namespace ThreadLib
{
// ========================================================================
// This is the handle-map global, only used in Win32.
// ========================================================================
#ifdef WIN32
std::map< DWORD, HANDLE > g_handlemap;
#endif
// ========================================================================
// Description: This is a "dummy" thread function that will be used to
// transparently translate function pointers to whatever
// system the user is currently compiling on.
// ========================================================================
#ifdef WIN32
DWORD WINAPI DummyRun( void* p_data )
#else
void* DummyRun( void* p_data )
#endif
{
// convert the dummy data
DummyData* data = (DummyData*)p_data;
// run the function with the given data
data->m_func( data->m_data );
// now delete the data
delete data;
// and return 0.
return 0;
}
} // end namespace ThreadLib
ThreadLibFunctions.h
Code
#ifndef THREADLIBFUNCTIONS_H
#define THREADLIBFUNCTIONS_H
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#ifdef WIN32 // windows95 and above
#include <windows.h>
#include <map>
#else // linux
#include <pthread.h>
#include <unistd.h>
#endif
#include "ThreadException.h"
namespace ThreadLib
{
// ========================================================================
// define the standard thread function format, which takes a void* as its
// parameter, and returns nothing
// ========================================================================
typedef void (*ThreadFunc)(void*);
// ========================================================================
// Define the standard ThreadID datatype, depending on the system
// ========================================================================
#ifdef WIN32 // windows95 and above
typedef DWORD ThreadID;
extern std::map< DWORD, HANDLE > g_handlemap;
#else // linux
typedef pthread_t ThreadID;
#endif
// ========================================================================
// Description: This is a "dummy" class that will be used to
// transparently translate function pointers to whatever
// system the user is currently compiling on. It is meant to
// be passed into the DummyRun function.
// ========================================================================
class DummyData
{
public:
ThreadFunc m_func;
void* m_data;
};
// ========================================================================
// Description: This is a "dummy" thread function that will be used to
// transparently translate function pointers to whatever
// system the user is currently compiling on.
// ========================================================================
#ifdef WIN32
DWORD WINAPI DummyRun( void* p_data );
#else
void* DummyRun( void* p_data );
#endif
// ========================================================================
// Description: Creates a thread and returns its ID.
// ========================================================================
inline ThreadID Create( ThreadFunc p_func, void* p_param )
{
ThreadID t;
// create a new dummy data block
DummyData* data = new DummyData;
data->m_func = p_func;
data->m_data = p_param;
#ifdef WIN32 // create a Win32 thread
HANDLE h;
h = CreateThread( NULL, 0, DummyRun, data, 0, &t );
if( h != 0 )
{
// insert the handle into the handlemap
g_handlemap[t] = h;
}
#else // create a linux thread
pthread_create( &t, 0, DummyRun, data );
#endif
if( t == 0 )
{
// delete the data first
delete data;
// throw an error
throw Exception( CreationFailure );
}
return t;
}
// ========================================================================
// Description: Get the ID of the current thread
// ========================================================================
inline ThreadID GetID()
{
#ifdef WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
// ========================================================================
// Description: This waits for a thread to finish executing before
// returning.
// ========================================================================
inline void WaitForFinish( ThreadID p_thread )
{
#ifdef WIN32
// look up the handle and wait for the thread to finish
WaitForSingleObject( g_handlemap[p_thread], INFINITE );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// "join" the thread. This essentially transfers control over to
// the thread and waits for it to finish.
pthread_join( p_thread, NULL );
#endif
}
// ========================================================================
// Description: This forcefully terminates a thread. Don't do this unless
// it is absolutely neccessary.
// ========================================================================
inline void Kill( ThreadID& p_thread )
{
#ifdef WIN32
// terminate the thread
TerminateThread( g_handlemap[p_thread], 0 );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// cancel the thread.
pthread_cancel( p_thread );
#endif
}
// ========================================================================
// Description: This yields the thread to the operating system, and gives
// up its current timeslice.
// ========================================================================
inline void YieldThread( int p_milliseconds = 1 )
{
#ifdef WIN32
Sleep( p_milliseconds );
#else
usleep( p_milliseconds * 1000 );
#endif
}
} // end namespace ThreadLib
#endif
#ifndef THREADLIBFUNCTIONS_H
#define THREADLIBFUNCTIONS_H
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#ifdef WIN32 // windows95 and above
#include <windows.h>
#include <map>
#else // linux
#include <pthread.h>
#include <unistd.h>
#endif
#include "ThreadException.h"
namespace ThreadLib
{
// ========================================================================
// define the standard thread function format, which takes a void* as its
// parameter, and returns nothing
// ========================================================================
typedef void (*ThreadFunc)(void*);
// ========================================================================
// Define the standard ThreadID datatype, depending on the system
// ========================================================================
#ifdef WIN32 // windows95 and above
typedef DWORD ThreadID;
extern std::map< DWORD, HANDLE > g_handlemap;
#else // linux
typedef pthread_t ThreadID;
#endif
// ========================================================================
// Description: This is a "dummy" class that will be used to
// transparently translate function pointers to whatever
// system the user is currently compiling on. It is meant to
// be passed into the DummyRun function.
// ========================================================================
class DummyData
{
public:
ThreadFunc m_func;
void* m_data;
};
// ========================================================================
// Description: This is a "dummy" thread function that will be used to
// transparently translate function pointers to whatever
// system the user is currently compiling on.
// ========================================================================
#ifdef WIN32
DWORD WINAPI DummyRun( void* p_data );
#else
void* DummyRun( void* p_data );
#endif
// ========================================================================
// Description: Creates a thread and returns its ID.
// ========================================================================
inline ThreadID Create( ThreadFunc p_func, void* p_param )
{
ThreadID t;
// create a new dummy data block
DummyData* data = new DummyData;
data->m_func = p_func;
data->m_data = p_param;
#ifdef WIN32 // create a Win32 thread
HANDLE h;
h = CreateThread( NULL, 0, DummyRun, data, 0, &t );
if( h != 0 )
{
// insert the handle into the handlemap
g_handlemap[t] = h;
}
#else // create a linux thread
pthread_create( &t, 0, DummyRun, data );
#endif
if( t == 0 )
{
// delete the data first
delete data;
// throw an error
throw Exception( CreationFailure );
}
return t;
}
// ========================================================================
// Description: Get the ID of the current thread
// ========================================================================
inline ThreadID GetID()
{
#ifdef WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
// ========================================================================
// Description: This waits for a thread to finish executing before
// returning.
// ========================================================================
inline void WaitForFinish( ThreadID p_thread )
{
#ifdef WIN32
// look up the handle and wait for the thread to finish
WaitForSingleObject( g_handlemap[p_thread], INFINITE );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// "join" the thread. This essentially transfers control over to
// the thread and waits for it to finish.
pthread_join( p_thread, NULL );
#endif
}
// ========================================================================
// Description: This forcefully terminates a thread. Don't do this unless
// it is absolutely neccessary.
// ========================================================================
inline void Kill( ThreadID& p_thread )
{
#ifdef WIN32
// terminate the thread
TerminateThread( g_handlemap[p_thread], 0 );
// close the handle of the thread
CloseHandle( g_handlemap[p_thread] );
// remove the handle from the map
g_handlemap.erase( p_thread );
#else
// cancel the thread.
pthread_cancel( p_thread );
#endif
}
// ========================================================================
// Description: This yields the thread to the operating system, and gives
// up its current timeslice.
// ========================================================================
inline void YieldThread( int p_milliseconds = 1 )
{
#ifdef WIN32
Sleep( p_milliseconds );
#else
usleep( p_milliseconds * 1000 );
#endif
}
} // end namespace ThreadLib
#endif
ThreadLibMutex.h
Code
#ifndef THREADLIBMUTEX_H
#define THREADLIBMUTEX_H
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#ifdef WIN32 // windows95 and above
#include <windows.h>
#else // linux
#include <pthread.h>
#endif
#include <string>
namespace ThreadLib
{
class Mutex
{
public:
// ====================================================================
// Description: Initialize the mutex object
// ====================================================================
Mutex()
{
#ifdef WIN32
// use critical sections in windows; much faster
InitializeCriticalSection( &m_mutex );
#else
pthread_mutex_init( &m_mutex, 0 );
#endif
}
// ====================================================================
// Description: Destroy the mutex object
// ====================================================================
~Mutex()
{
#ifdef WIN32
DeleteCriticalSection( &m_mutex );
#else
pthread_mutex_destroy( &m_mutex );
#endif
}
// ====================================================================
// Description: Wait for a lock, then hold the lock
// ====================================================================
inline void Lock()
{
#ifdef WIN32
EnterCriticalSection( &m_mutex );
#else
pthread_mutex_lock( &m_mutex );
#endif
}
// ====================================================================
// Description: release the lock
// ====================================================================
inline void Unlock()
{
#ifdef WIN32
LeaveCriticalSection( &m_mutex );
#else
pthread_mutex_unlock( &m_mutex );
#endif
}
protected:
// define the base mutex types
#ifdef WIN32
CRITICAL_SECTION m_mutex;
#else
pthread_mutex_t m_mutex;
#endif
}; // end class Mutex
} // end namespace ThreadLib
#endif
#ifndef THREADLIBMUTEX_H
#define THREADLIBMUTEX_H
// ============================================================================
// Include Files for the threading libraries
// ============================================================================
#ifdef WIN32 // windows95 and above
#include <windows.h>
#else // linux
#include <pthread.h>
#endif
#include <string>
namespace ThreadLib
{
class Mutex
{
public:
// ====================================================================
// Description: Initialize the mutex object
// ====================================================================
Mutex()
{
#ifdef WIN32
// use critical sections in windows; much faster
InitializeCriticalSection( &m_mutex );
#else
pthread_mutex_init( &m_mutex, 0 );
#endif
}
// ====================================================================
// Description: Destroy the mutex object
// ====================================================================
~Mutex()
{
#ifdef WIN32
DeleteCriticalSection( &m_mutex );
#else
pthread_mutex_destroy( &m_mutex );
#endif
}
// ====================================================================
// Description: Wait for a lock, then hold the lock
// ====================================================================
inline void Lock()
{
#ifdef WIN32
EnterCriticalSection( &m_mutex );
#else
pthread_mutex_lock( &m_mutex );
#endif
}
// ====================================================================
// Description: release the lock
// ====================================================================
inline void Unlock()
{
#ifdef WIN32
LeaveCriticalSection( &m_mutex );
#else
pthread_mutex_unlock( &m_mutex );
#endif
}
protected:
// define the base mutex types
#ifdef WIN32
CRITICAL_SECTION m_mutex;
#else
pthread_mutex_t m_mutex;
#endif
}; // end class Mutex
} // end namespace ThreadLib
#endif
调用线程库的main.cpp文件
Code
#include <iostream>
using namespace std;
#include "../ThreadLib/ThreadLib.h"
ThreadLib::Mutex m;
void PrintThread( void* data )
{
// convert the data passed in into a character.
char* c = (char*)data;
for( int i = 0; i < 200; i++ )
{
m.Lock();
for( int j = 0; j < 50; j++ )
{
cout << c;
cout.flush();
}
m.Unlock();
}
}
int main()
{
ThreadLib::ThreadID a, b;
a = ThreadLib::Create( PrintThread, (void*)"12" );
b = ThreadLib::Create( PrintThread, (void*)"34" );
ThreadLib::WaitForFinish( b );
ThreadLib::WaitForFinish( a );
char c;
cin >> c;
return 0;
}
#include <iostream>
using namespace std;
#include "../ThreadLib/ThreadLib.h"
ThreadLib::Mutex m;
void PrintThread( void* data )
{
// convert the data passed in into a character.
char* c = (char*)data;
for( int i = 0; i < 200; i++ )
{
m.Lock();
for( int j = 0; j < 50; j++ )
{
cout << c;
cout.flush();
}
m.Unlock();
}
}
int main()
{
ThreadLib::ThreadID a, b;
a = ThreadLib::Create( PrintThread, (void*)"12" );
b = ThreadLib::Create( PrintThread, (void*)"34" );
ThreadLib::WaitForFinish( b );
ThreadLib::WaitForFinish( a );
char c;
cin >> c;
return 0;
}