⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutex.c

📁 用c++包装好的线程库,直接拿来使用,提高效率.
💻 C
字号:
//// class mutex//// Mutes is a semaphore, that can be used by two threads to mutually// exclude the other.  To ensure uniqe access to memory.#include "thread.h"#include "mutex.h"#include "exception.h"#include "thread_lists.h"#include "wait_queue.h"#include "shared.h"#include <cerrno>#define  MUTEX_MAGIC_NO        0x212612namespace cpp_threads {  std::string Mutex::_project = "";  Mutex::Mutex(attributes::scope scope_p)  {    init( scope_p );  }  Mutex::Mutex()  {    Pthread *p = Pthread::self();    scope_t scope = attributes::process_private_e;    Pthread::debug("Mutex::Mutex()");    if( p && p->inherit() )      scope = p->scope();    init( scope );  }  Mutex::~Mutex()  {    Pthread::debug("Mutex::~Mutex");    if ( _m ) {      _m->m_spinlock.acquire();      delete _waiting;      if ( _scope == attributes::process_private_e )	delete _m;      else	SharedMemory::share.deAlloc( _m );      _m = 0;    }  }  void Mutex::init(attributes::scope scope_p)  {    _id = -1;    if ( scope_p == attributes::process_private_e ) {      _m            = new storage;      _m->m_magic   = 0;    } else {      _id           = SharedMemory::share.createProj( _project );      _m            = (storage*)SharedMemory::share.alloc( sizeof(storage),_id );      if( _m != (storage *)-1 )	exception::fatal( ENOMEM );    }    if ( _m->m_magic != MUTEX_MAGIC_NO ) {      _m->m_kind    = fast_e;      _m->m_count   = 0;      _m->m_owner   = -1;      _m->m_magic   = MUTEX_MAGIC_NO;    }    _waiting        = new WaitQueue( _id );    _scope          = scope_p;  }  attributes::scope Mutex::scope()  {    return _scope;  }  int Mutex::isLocked()  {    bool rv;    _m->m_spinlock.acquire();    rv = (_m->m_count != 0);    _m->m_spinlock.release();    return rv;  }  void Mutex::release()  {    _m->m_owner     = 0;    _m->m_count     = 0;    _m->m_exclusive = false;  }  int Mutex::acquire(bool xlsive_p)  {    // The owner, is the one holding the exclusive lock.    _m->m_exclusive  = xlsive_p;    _m->m_owner      = getpid();    _m->m_count++;    return 0;  }  //  // kind  //  // set the mutex kind.  int Mutex::kind(mutex_kind kind_p)  {    if (kind_p != Mutex::recursive_e && kind_p != Mutex::fast_e)      return EINVAL;    _m->m_kind = kind_p;    return 0;  }  //  // kind  //  // get the mutex kind.  int Mutex::kind()  {    return _m->m_kind;  }  //  // trylock  //  // try and lock the mutex.  //  // return  //   EBUSY  - the mutex is locked by another.  //   EINVAL - the mutex is of an unknown kind.  //   0      - successful.  int Mutex::tryLock(bool xlsive_p)  {    int rval = EBUSY;    bool read_lock;        _m->m_spinlock.acquire();    read_lock = !(xlsive_p || _m->m_exclusive);    switch(_m->m_kind) {    case Mutex::fast_e:      if ( _m->m_count == 0 || read_lock )	rval = acquire(xlsive_p);      break;    case Mutex::recursive_e:      if ( _m->m_count == 0 || _m->m_owner == getpid() || read_lock )	rval = acquire(xlsive_p);      break;    case Mutex::errorcheck_e:      if ( _m->m_count == 0 || read_lock )	rval = acquire(xlsive_p);      else	if ( _m->m_owner == getpid() )	  rval = EDEADLK;      break;    default:      rval = EINVAL;      break;    }    _m->m_spinlock.release();    return rval;  }  //  // lock  //  // Try and lock the mutex.  If unsuccessful, suspend the calling  // process, until the mutex is available.  int Mutex::lock(bool xlsive_p, int pri_p)  {    int rval = EBUSY;        while(rval == EBUSY) {      if ((rval = tryLock(xlsive_p)) == EBUSY)	_waiting->suspendMe(pri_p);    }    return rval;  }  //  // unlock  //  // unlock the mutex, and restart any threads, that are waiting  // on it.  int Mutex::unLock()  {    bool read_lock;    int rval = 0;    _m->m_spinlock.acquire();    read_lock = !_m->m_exclusive;    switch(_m->m_kind) {    case Mutex::fast_e:      if ( read_lock || _m->m_owner == getpid() )	release();      else	rval = EBUSY;      break;    case Mutex::recursive_e:      if ( (read_lock || _m->m_owner == getpid()) && _m->m_count > 0 ) {	if (--_m->m_count == 0)	  release();      } else	rval = EBUSY;      break;    case Mutex::errorcheck_e:      if ( _m->m_count == 0 || (_m->m_owner != getpid() && !read_lock) )	rval = EPERM;      else	release();      break;    default:      rval = EINVAL;    }    _m->m_spinlock.release();    if ( rval == 0 )      _waiting->wakeUp();    return rval;  }  //  // project_part  //  // change the project part  void  Mutex::projectPart(const std::string& part_p)  {    _project = part_p;  }  Mutex::operator bool()  {    return isLocked();  }}; // Namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -