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

📄 thread.cpp

📁 遗传算法的一个库
💻 CPP
字号:
/* * part of GradSoft C++ ToolBox * (C) GradSoft 2000,2001 * http://www.gradsoft.com.ua * $Id: Thread.cpp,v 1.43 2001/10/31 03:13:50 rssh Exp $ */#include <GradSoft/Thread.h>#include <GradSoft/ThreadEvent.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SCHED_H#include <sched.h>#endif#ifndef __GradSoft_vector_INCLUDED#include <vector>#define __GradSoft_vector_INCLUDED#endif#ifdef WIN32#include <windows.h>#endif#include <assert.h>using namespace std;namespace GradSoft{#ifdef HAVE_PTHREAD_HThread::Thread() throw (ThreadingExceptions::NoMemory) {  id_ = 0;  error_code_ = pthread_attr_init(&attr_);  running_=false;  in_cleanup_=false;  ThreadingError::checkError(error_code_,"pthread_attr_init");  pthread_mutex_init(&idMutex_,0);}Thread::~Thread() { pthread_mutex_lock(&idMutex_); if (id_ == pthread_self()) {   pthread_mutex_unlock(&idMutex_);   // we are descructed from themself   // so, it was call "delete this" from run   if (!in_cleanup_) {     pthread_detach(id_);     running_ = false;     pthread_cleanup_push(thread_cleanup_process,this);     in_cleanup_ = true;     pthread_exit(NULL);     pthread_cleanup_pop(1); //  useless for our purpose, but Solaris require   }else{     pthread_attr_destroy(&attr_);     pthread_mutex_destroy(&idMutex_);   } }else{   pthread_mutex_unlock(&idMutex_);   if (is_running()) {     cancel();   }   join(*this);   pthread_attr_destroy(&attr_);   pthread_mutex_destroy(&idMutex_); }}void* Thread::thread_process(void* v)  throw(){ Thread* th = (Thread*)(v); assert(th!=NULL); try {  {   WriteLocker wl(th->runningRWLock_);   th->running_ = true;  }  pthread_mutex_lock(&th->idMutex_);  // wait until id_ is set.  pthread_mutex_unlock(&th->idMutex_);  th->run();  {   WriteLocker wl(th->runningRWLock_);   th->running_ = false;  }  pthread_exit(NULL); }catch(...){  {   th->running_ = false;   th->error_code_ = -1;   throw;  }  //pthread_exit(th); } return NULL;}void  Thread::thread_cleanup_process(void* v) {  Thread* th = (Thread*)(v);  delete th;}void Thread::start()                     throw  (ThreadingExceptions::NoResources,                             ThreadingExceptions::InternalError)  { pthread_mutex_lock(&idMutex_); int errcode =  pthread_create(&id_, &attr_, thread_process, this); pthread_mutex_unlock(&idMutex_); ThreadingError::checkError(errcode,"pthread_create");}bool Thread::is_running() const throw(ThreadingExceptions::NoResources,                                      ThreadingExceptions::InternalError){ ReadLocker rl(runningRWLock_); return running_;}void Thread::cancel() throw(){ error_code_=pthread_cancel(id_); if (error_code_==0) {   WriteLocker wl(runningRWLock_);   running_=false; }}void Thread::join(const id_type& id) throw(){ if (id == pthread_self()) return; pthread_join(id,NULL);}void Thread::yield(){ sched_yield();}void Thread::exit(void) throw(){ pthread_exit(NULL);}void Thread::sleep(unsigned int nseconds) throw(){ sleepCurrent(nseconds);}void Thread::sleepCurrent(unsigned int nseconds) throw(){#ifdef __linux__pthread_testcancel();#endifyield();::sleep(nseconds);#ifdef __linux__pthread_testcancel();#endif}void Thread::nanosleep(unsigned int nseconds, long nnanoseconds) throw(){ nanosleepCurrent(nseconds, nnanoseconds);}void Thread::nanosleepCurrent(unsigned int nseconds, long nnanoseconds) throw(){#ifdef __linux__pthread_testcancel();#endifyield();timespec req;req.tv_sec=nseconds;req.tv_nsec=nseconds;::nanosleep(&req,0);#ifdef __linux__pthread_testcancel();#endif}void Thread::testcancel(void) throw(){pthread_testcancel();}Thread::id_type Thread::current_id() throw(){ return pthread_self();}#else# if defined(WIN32)//// class to support for "delete this" syntax // for Thread instance//class SuicideHelper: public Thread{private:  // used to say the run(),   // there are threads to be deleted or the work must be finished  ThreadEvent rotate_;  // this is list of threads to be deleted  vector<Thread*> threads_;    // used to lock/unlock threads_ handling  Mutex threads_lock_;public:   ///  SuicideHelper();  ///  ~SuicideHelper();  ///  void run();  // method to be invoked by ~Thread() destructor  void deleteThread(Thread* thread_ptr);};SuicideHelper::SuicideHelper(){}SuicideHelper::~SuicideHelper(){  if(is_running()){  	cancel();    rotate_.notify();  }}void SuicideHelper::deleteThread(Thread* thread_ptr){  threads_lock_.lock();  threads_.push_back(thread_ptr);  threads_lock_.unlock();  if(is_running()) rotate_.notify();  else start();}void SuicideHelper::run(){  do{    threads_lock_.lock();    for(int i=0;i<threads_.size();++i)    {      delete threads_[i];    }    threads_.clear();    threads_lock_.unlock();    rotate_.wait();    testcancel();  }while(true);}static SuicideHelper cleaner;Thread::Thread(){  id_ = 0;  error_code_ = 0;  running_=false;  do_break_=false;}Thread::~Thread(){  do_break_=true;  {     MutexLocker ml(idMutex_);    if (id_==0) return;  }  StrExTranslator se;  se.touch();  if(threadID_ == GetCurrentThreadId()){    cleaner.deleteThread(this);    exit();  }else{    // if (is_running()) cancel();    join(*this);    if (!CloseHandle(id_)){      ThreadingError::lastErrorNotification();    }  }}void* Thread::thread_process(void* v){  Thread* th = (Thread*)v;  try{    {      WriteLocker wl(th->runningRWLock_);      th->running_ = true;      MutexLocker ml(th->idMutex_);    }    if(!th->do_break_) th->run();    {      WriteLocker wl(th->runningRWLock_);      th->running_ = false;    }  }catch(...){   th->running_ = false;   th->error_code_ = -1;   throw;  }  StrExTranslator se;  se.touch();  ExitThread(0);  return NULL;}void Thread::start(){  {  StrExTranslator se;  se.touch();  MutexLocker ml(idMutex_);  id_=CreateThread(       NULL, // the handle cannot be inherited        0,    // default initial size of the stack,              // the same as the calling thread       (LPTHREAD_START_ROUTINE)thread_process,              // pointer to the application-defined function              // being executed by the thread        (void*)this, // parameter value passed to the thread       0,    // means the thread runs immediately after creation       &threadID_              // NB: variable that receives the thread identifier.      );   }  if (id_ == NULL){    ThreadingError::lastErrorNotification();  }}void Thread::cancel(){  do_break_=true;}bool Thread::is_running() const throw (ThreadingExceptions::NoResources,                                  ThreadingExceptions::InternalError){   ReadLocker rl(runningRWLock_);   return running_;}void Thread::exit() {  {    WriteLocker wl(runningRWLock_);    running_=false;  }  {    StrExTranslator se;    se.touch();    ExitThread(0);  }}void Thread::testcancel() {  StrExTranslator se;  se.touch();  if(threadID_==GetCurrentThreadId()){    if(do_break_){       exit();    }  }}void Thread::sleep(unsigned int sec){   Sleep(sec*1000);   testcancel(); }void Thread::nanosleep(unsigned int nseconds, long nnanoseconds) throw(){   Sleep(nseconds*1000 + nnanoseconds%1000);   testcancel(); }void Thread::sleepCurrent(unsigned int sec){   Sleep(sec*1000);}void Thread::nanosleepCurrent(unsigned int nseconds, long nnanoseconds) throw(){   Sleep(nseconds*1000 + nnanoseconds%1000);}void Thread::yield(){  StrExTranslator se;  se.touch();  Sleep(0);}void Thread::join(const id_type& id){  StrExTranslator se;  se.touch();  if (id == GetCurrentThread()) return;  if (WaitForSingleObject(id,INFINITE)==WAIT_FAILED) {    ThreadingError::lastErrorNotification();  }}Thread::id_type Thread::current_id() throw(){  StrExTranslator se;  se.touch();  return (HANDLE)GetCurrentThreadId();}# else#  error "Non HAVE_PTHREAD_H non WIN32 are defined"# endif#endif}

⌨️ 快捷键说明

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