Thread4z:跨平台线程

Thread4z

Thread4z 是一款开源的C++轻量级跨平台线程库.
Thread4z is an open source C++ lightweight cross-platform thread library.

Introduction

  1. 封装了线程的创建销毁管理类 CThread , 此包装屏蔽了linux/windows的接口差异部分, 只需要继承该类即可轻松享受并发编程[package of thread creation, destruction and management CThread, this packaging shielding interface between linux/windows parts, needs only to extend this class can easily enjoy concurrent programming].
  2. 封装了性能极佳的用户态线程锁CLock, 使用linux的mutex与windows的临界区实现并消除系统带来的差异部分[package of userland threads have the excellent performance of the lock CLock, mutex and windows critical region using Linux implementation and eliminate difference between system parts].
  3. 使用CLock类进一步包装了智能的CAutoLock, 在需要加锁的地方直接创建该类便可实现自动上锁和退出语句块自动退锁[The 3 uses the CLock class to further packaging intelligent CAutoLock, create the class directly to realize the automatic locking and exit statement block automatic back to lock in the need for locks in place].
  4. 封装了匿名信号量(进程内)和具名信号量(可跨进程使用) CSem, 满足进程间互斥, 进程间和进程内事件通知, 资源计数共享等特殊同步需求[packaging anonymous signal (process) and named semaphores (the process) CSem, meet the mutex between processes, the course of events and process resource sharing and other special notice, count synchronization requirements].
  5. 封装了部分原子操作AtomicAdd,AtomicInc,AtomicDec, 对于简单的计数等操作可通过此接口进行操作,可实现比用户态线程锁更极速的操作性能[packaging part of atomic operations AtomicAdd, AtomicInc, AtomicDec, for simple counting operation can be operated through this interface, can realize the lock operation performance is more extreme than the user mode threads].


 
 
/*
* Thread4z License
* -----------
*
* Thread4z is licensed under the terms of the MIT license reproduced below.
* This means that Thread4z is free software and can be used for both academic
* and commercial purposes at absolutely no cost.
*
*
* ===============================================================================
*
* Copyright (C) 2010-2013 YaweiZhang <yawei_zhang@foxmail.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* ===============================================================================
*
* (end of COPYRIGHT)
*/
/*
* AUTHORS: YaweiZhang <yawei_zhang@foxmail.com>
* VERSION: 1.0.0
* PURPOSE: A lightweight & cross platform library for multi-thread.
* CREATION: 2010.9.26
* LCHANGE: 2013.03.-
* LICENSE: Expat/MIT License, See Copyright Notice at the begin of this file.
*/
/*
*
* QQ Group: 19811947
* Web Site: www.zsummer.net
* mail: yawei_zhang@foxmail.com
*/
/*
* UPDATES
*
* VERSION 0.1.0 <DATE: 2010.9.26>
* packet CThread, CLock under the Windows.
*
* VERSION 0.2.0 <DATE: 2011.3.19>
* packet CThread, CLock under the Linux.
* packet CSem under the Windows and Linux.
*
* VERSION 0.2.1 <DATE: 2012.4.27>
* packet Atom under the Windows and Linux.
*
* VERSION 0.2.2 <DATE: 2012.12.21>
* change CLock detail that set mutex's attribute 'PTHREAD_MUTEX_RECURSIVE' under the linux.
*
* VERSION 1.0.0 <DATE: 2013.06.10>
* update 1.0.0
*
*
*/
#pragma once
#ifndef _ZSUMMER_THREAD_H_
#define _ZSUMMER_THREAD_H_
#ifdef WIN32
#include <WinSock2.h>
#include <Windows.h>
#else
#include<pthread.h>
#include<semaphore.h>
#endif
#ifndef _ZSUMMER_BEGIN
#define _ZSUMMER_BEGIN namespace zsummer {
#endif
#ifndef _ZSUMMER_THREAD_BEGIN
#define _ZSUMMER_THREAD_BEGIN namespace thread4z {
#endif
_ZSUMMER_BEGIN
_ZSUMMER_THREAD_BEGIN
//! 线程类封装
//! 通过继承该类并覆写Run()函数进行使用
//! Start调用将创建一个线程去执行Run函数.
//! Wait调用将阻塞当前调用者线程直到CThread线程退出.
//! Terminate调用将强制终止CThread线程, 改掉用应慎用!
class CThread
{
public:
CThread ();
virtual ~ CThread ();
//interface
public:
bool Start ();
virtual void Run () = 0 ;
bool Wait ();
bool Terminate ();
//可通过对返回值强制转换为windows下的handle
inline unsigned long long GetThread () { return m_hThread ;};
private:
unsigned long long m_hThread ;
};
//! 信号量
//! Create创建信号量 并指定初始信号数量
//! Open创建一个已存在的具名信号量
//! Wait调用 等待信号
//! Post调用 投递一个信号
class CSem
{
public:
CSem ();
virtual ~ CSem ();
public:
//! initcount 初始化信号量个数
//! name 如果不为NULL 则创建一个具名信号量, 可用Open跨进程打开.
bool Create ( int initcount , const char * name );
//! 打开一个具名信号量对象
bool Open ( const char * name );
//! timeout <= 0 为直到有信号才返回 否则超时也会返回
bool Wait ( int timeout = 0 );
//发送一个信号
bool Post ();
private:
#ifdef WIN32
HANDLE m_hSem ;
#else
sem_t m_semid ;
sem_t * m_psid ;
char m_name [ 260 ];
#endif
};
//! 线程锁
//! linux使用递归mutex, windows下使用临界区, 均为递归锁实现.
//! Lock调用开始锁定资源
//! Unlock调用释放资源锁定.
class CLock
{
public:
CLock ();
virtual ~ CLock ();
public:
void Lock ();
void UnLock ();
private:
#ifdef WIN32
CRITICAL_SECTION m_crit ;
#else
pthread_mutex_t m_crit ;
#endif
};
//! 快速线程锁
class CAutoLock
{
public:
explicit CAutoLock ( CLock & lk ) : m_lock ( lk )
{
m_lock . Lock ();
}
~ CAutoLock ()
{
m_lock . UnLock ();
}
private:
CLock & m_lock ;
};
//! 原子操作
int AtomicAdd ( volatile int * pt , int t );
int AtomicInc ( volatile int * pt );
int AtomicDec ( volatile int * pt );
#ifndef _ZSUMMER_END
#define _ZSUMMER_END }
#endif
#ifndef _ZSUMMER_THREAD_END
#define _ZSUMMER_THREAD_END }
#endif
_ZSUMMER_THREAD_END
_ZSUMMER_END
#endif



  
  
/*
* Thread4z License
* -----------
*
* Thread4z is licensed under the terms of the MIT license reproduced below.
* This means that Thread4z is free software and can be used for both academic
* and commercial purposes at absolutely no cost.
*
*
* ===============================================================================
*
* Copyright (C) 2010-2013 YaweiZhang <yawei_zhang@foxmail.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* ===============================================================================
*
* (end of COPYRIGHT)
*/
#include "thread.h"
#include <time.h>
#include <string.h>
#ifndef WIN32
#include <string.h>
#include <fcntl.h>
#else
#include <process.h>
#endif
#ifndef zs_th_s
#define zs_th_s zsummer::thread4z
#endif
zs_th_s :: CThread :: CThread ()
{
m_hThread = 0 ;
}
zs_th_s :: CThread ::~ CThread ()
{
}
#ifdef WIN32
static unsigned int WINAPI ThreadProc ( LPVOID lpParam )
{
zs_th_s :: CThread * p = ( zs_th_s :: CThread * ) lpParam ;
p -> Run ();
_endthreadex ( 0 );
return 0 ;
}
#else
static void * ThreadProc ( void * pParam )
{
zs_th_s :: CThread * p = ( zs_th_s :: CThread * ) pParam ;
p -> Run ();
return NULL ;
}
#endif
bool zs_th_s :: CThread :: Start ()
{
#ifdef WIN32
unsigned long long ret = _beginthreadex ( NULL , 0 , ThreadProc , ( void * ) this , 0 , NULL );
if ( ret == - 1 || ret == 1 || ret == 0 )
{
return false ;
}
m_hThread = ret ;
#else
pthread_t ptid = 0 ;
int ret = pthread_create ( & ptid , NULL , ThreadProc , ( void * ) this );
if ( ret != 0 )
{
return false ;
}
m_hThread = ptid ;
#endif
return true ;
}
bool zs_th_s :: CThread :: Wait ()
{
#ifdef WIN32
if ( WaitForSingleObject (( HANDLE ) m_hThread , INFINITE ) != WAIT_OBJECT_0 )
{
return false ;
}
#else
if ( pthread_join (( pthread_t ) m_hThread , NULL ) != 0 )
{
return false ;
}
#endif
return true ;
}
bool zs_th_s :: CThread :: Terminate ()
{
#ifdef WIN32
return TerminateThread (( HANDLE ) m_hThread , 1 ) ? true : false ;
#else
return pthread_cancel (( pthread_t ) m_hThread ) == 0 ? true : false ;
#endif
}
zs_th_s :: CSem :: CSem ()
{
#ifndef WIN32
memset ( m_name , 0 , sizeof ( m_name ));
#endif
}
zs_th_s :: CSem ::~ CSem ()
{
#ifdef WIN32
if ( m_hSem != NULL )
{
CloseHandle ( m_hSem );
m_hSem = NULL ;
}
#else
if ( strlen ( m_name ) == 0 )
{
sem_destroy ( & m_semid );
}
else
{
sem_close ( m_psid );
sem_unlink ( m_name );
memset ( m_name , 0 , sizeof ( m_name ));
}
#endif
}
bool zs_th_s :: CSem :: Create ( int initcount , const char * name )
{
if ( initcount < 0 )
{
initcount = 0 ;
}
#ifdef WIN32
if ( initcount > 64 )
{
return false ;
}
m_hSem = CreateSemaphoreA ( NULL , initcount , 64 , name );
if ( m_hSem == NULL )
{
return false ;
}
#else
if ( name == NULL || strlen ( name ) == 0 )
{
if ( sem_init ( & m_semid , 0 , initcount ) != 0 )
{
return false ;
}
}
else
{
if ( strlen ( name ) > 256 )
{
int * p = NULL ;
* p = 3 ;
return false ;
}
strcpy ( m_name , name );
m_psid = sem_open ( name , O_CREAT , 0644 , initcount );
if ( m_psid == SEM_FAILED )
{
return false ;
}
}
#endif
return true ;
}
bool zs_th_s :: CSem :: Open ( const char * name )
{
if ( name == NULL )
{
return false ;
}
if ( strlen ( name ) == 0 )
{
return false ;
}
#ifdef WIN32
m_hSem = OpenSemaphoreA ( SEMAPHORE_ALL_ACCESS , FALSE , name );
if ( m_hSem == NULL )
{
return false ;
}
#else
if ( strlen ( name ) > 256 )
{
return false ;
}
strcpy ( m_name , name );
m_psid = sem_open ( name , O_EXCL );
if ( m_psid == SEM_FAILED )
{
return false ;
}
#endif
return true ;
}
bool zs_th_s :: CSem :: Wait ( int timeout )
{
#ifdef WIN32
if ( timeout <= 0 )
{
timeout = INFINITE ;
}
if ( WaitForSingleObject ( m_hSem , timeout ) != WAIT_OBJECT_0 )
{
return false ;
}
#else
if ( strlen ( m_name ) == 0 )
{
if ( timeout <= 0 )
{
return ( sem_wait ( & m_semid ) == 0 );
}
else
{
timespec ts ;
clock_gettime ( CLOCK_REALTIME , & ts );
ts . tv_sec += timeout / 1000 ;
ts . tv_nsec += ( timeout % 1000 ) * 1000000 ;
return ( sem_timedwait ( & m_semid , & ts ) == 0 );
}
}
else
{
if ( timeout <= 0 )
{
return ( sem_wait ( m_psid ) == 0 );
}
else
{
timespec ts ;
clock_gettime ( CLOCK_REALTIME , & ts );
ts . tv_sec += timeout / 1000 ;
ts . tv_nsec += ( timeout % 1000 ) * 1000000 ;
return ( sem_timedwait ( m_psid , & ts ) == 0 );
}
}
#endif
return true ;
}
bool zs_th_s :: CSem :: Post ()
{
#ifdef WIN32
return ReleaseSemaphore ( m_hSem , 1 , NULL ) ? true : false ;
#else
if ( strlen ( m_name ) == 0 )
{
return ( sem_post ( & m_semid ) == 0 );
}
else
{
return ( sem_post ( m_psid ) == 0 );
}
#endif
}
zs_th_s :: CLock :: CLock ()
{
#ifdef WIN32
InitializeCriticalSection ( & m_crit );
#else
//m_crit = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutexattr_t attr ;
pthread_mutexattr_init ( & attr );
pthread_mutexattr_settype ( & attr , PTHREAD_MUTEX_RECURSIVE );
pthread_mutex_init ( & m_crit , & attr );
pthread_mutexattr_destroy ( & attr );
#endif
}
zs_th_s :: CLock ::~ CLock ()
{
#ifdef WIN32
DeleteCriticalSection ( & m_crit );
#else
pthread_mutex_destroy ( & m_crit );
#endif
}
void zs_th_s :: CLock :: Lock ()
{
#ifdef WIN32
EnterCriticalSection ( & m_crit );
#else
pthread_mutex_lock ( & m_crit );
#endif
}
void zs_th_s :: CLock :: UnLock ()
{
#ifdef WIN32
LeaveCriticalSection ( & m_crit );
#else
pthread_mutex_unlock ( & m_crit );
#endif
}
//------------------------------------------------------------------
int zs_th_s :: AtomicAdd ( volatile int * pt , int t )
{
#ifdef WIN32
return ( int ) InterlockedExchangeAdd (( long * ) pt , ( long ) t );
#else
// return __gnu_cxx::__exchange_and_add(pt, t);
return __sync_add_and_fetch ( pt , t );
//return *++pt;
#endif
}
int zs_th_s :: AtomicInc ( volatile int * pt )
{
#ifdef WIN32
return ( int ) InterlockedIncrement (( long * ) pt );
#else
//return __gnu_cxx::__exchange_and_add(pt, 1);
return __sync_add_and_fetch ( pt , 1 );
#endif
}
int zs_th_s :: AtomicDec ( volatile int * pt )
{
#ifdef WIN32
return ( int ) InterlockedDecrement (( long * ) pt );
#else
//return __gnu_cxx::__exchange_and_add(pt, -1);
return __sync_add_and_fetch ( pt , - 1 );
#endif
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值