C++线程Thread类库1

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "include.h"
using namespace clib;

// external functions
// I placed it here, just because I don't want to include those many header files. : (
void lib_protected_init(void);


#define THREADTABLE_SIZE 1024                 //最大的线程数目
#define MAX_WAIT_TIME_LENGTH 5*1000          //最长等待时间为5s

struct threadinfo                           //线程信息结构体
{
#ifndef WIN32
 pthread_t self;                 //线程本身
#else
 long self;
#endif
 const char *name;               //线程名字
 CThread::thread_func_t *func;      //成员函数指针
 long number;                      //线程序号

#ifndef WIN32
 int wakefd_recv;               //接收句柄             
 int wakefd_send;               //发送句柄
 pthread_cond_t exiting;        //线程信号量
#else
 HANDLE wake_handle;               //事件句柄
 HANDLE exiting;                   //事件句柄
#endif
};                                       

struct new_thread_args           //新的线程数据参数结构体
 {
 CThread::thread_func_t *func;     //成员函数指针
 void *arg;                         //线程参数
 struct threadinfo *ti;           线程信息结构体
};


static struct threadinfo *threadtable[THREADTABLE_SIZE];     //建立一个线程信息结构体指针数组threadtable
#define THREAD(t) (threadtable[(t) % THREADTABLE_SIZE])      //


static long active_threads = 0;                  //当前活跃的线程数量


static long started_threads = 0;              //已经创建开始的线程数


static long next_threadnumber;               //下一个可用的要创建的线程序号     


static struct threadinfo mainthread;              //   //主线程信息结构体


static int iInitilizated = 0;                   //初始化为0

#ifndef WIN32

pthread_key_t tsd_key;                         //线程键key
static pthread_mutex_t *threadtable_lock = NULL;    //线程mutex锁
#else
static CRITICAL_SECTION *threadtable_lock = NULL;    //线程CRITICAL临界区
#endif

static void lock(void)                          //这是该类主要的上锁函数
 {
#ifndef WIN32
 int ret;
 if (!threadtable_lock)
  return;

 ret = pthread_mutex_lock(threadtable_lock);           //mutex线程上锁

 if (ret != 0)
 {
  error(ret, "ssthread-pthread: could not lock thread table:%s", strerror(errno));
  //panic(ret, "thread-pthread: could not lock thread table");
 }
#else
 if (!threadtable_lock)
  return;

 EnterCriticalSection(threadtable_lock);            //线程上锁CriticalSection
#endif
}

static void unlock(void) {                             //这是该类主要的上锁函数
#ifndef WIN32
 int ret;

 if (!threadtable_lock)                              
  return;

 ret = pthread_mutex_unlock(threadtable_lock);        //线程解锁mutex

 if (ret != 0)
 {
  error(ret, "thread-pthread: could not unlock thread table:%s", strerror(errno));
  //panic(ret, "thread-pthread: could not unlock thread table");
 }
#else
 if (threadtable_lock)
  LeaveCriticalSection(threadtable_lock);          //线程解锁CriticalSection
 return;
#endif
}


static void flushpipe(int fd) {               //清空pipe管道,fd为管道句柄
 unsigned char buf[128];                   
 size_t bytes;

 do {
#ifndef WIN32
  bytes = read(fd, buf, sizeof(buf));         //将管道pipe句柄中的数据全部清空
#else
  bytes = _read(fd, buf, sizeof(buf));
#endif
 } while (bytes > 0);
}

// I copy it from socket.cpp
static int socket_set_blocking(int fd, int blocking)                //将socket句柄设置为阻塞,非阻塞
{
#ifndef WIN32
    int flags, newflags;

    flags = fcntl(fd, F_GETFL);             //设置类型
    if (flags < 0) {
        error(errno, "cannot get flags for fd %d", fd);
        return -1;
    }

    if (blocking)                           //如果是阻塞模式
        newflags = flags & ~O_NONBLOCK;
    else
        newflags = flags | O_NONBLOCK;      

    if (newflags != flags) {
        if (fcntl(fd, F_SETFL, newflags) < 0) {
            error(errno, "cannot set flags for fd %d", fd);
            return -1;
        }
    }

    return 0;
#else
 return -1;
#endif
}


#ifndef WIN32
static long fill_threadinfo(pthread_t id, const char *name,
       thread_func_t *func,
#else   
static long fill_threadinfo(long id, const char *name,
       CThread::thread_func_t *func,   
#endif
struct threadinfo *ti) {  
#ifndef WIN32
 int pipefds[2];               //两个管道句柄
 int ret = 0;
#endif
 long first_try;                  

 c_assert(active_threads < THREADTABLE_SIZE);     //确保当前活跃的线程数量 小于 线程信息数组的线程数量

 ti->self = id;                        //填充线程信息id
 ti->name = name;                       //填充线程名字
 ti->func = func;                      //填充线程函数指针

#ifndef WIN32
 if (pipe(pipefds) < 0)                  //为该线程分配两个管道句柄
 {
  error(ret, "cannot allocate wakeup pipe for new thread:%s", strerror(errno));
  //panic(errno, "cannot allocate wakeup pipe for new thread");
 }
 ti->wakefd_recv = pipefds[0];            //接收管道句柄
 ti->wakefd_send = pipefds[1];            //发送管道句柄
 socket_set_blocking(ti->wakefd_recv, 0);       //为管道设置非阻塞模式
 socket_set_blocking(ti->wakefd_send, 0);

 ret = pthread_cond_init(&ti->exiting, NULL);     //初始化信号量
 if (ret != 0)
 {
  error(ret, "cannot create condition variable for new thread:%s", strerror(errno));
//  panic(ret, "cannot create condition variable for new thread");
 }
#else
 ti->exiting  = CreateEvent(NULL, TRUE, FALSE, NULL);     //创建退出信号事件
 ti->wake_handle = CreateEvent(NULL, TRUE, FALSE, NULL);      //创建叫醒事件

 if (ti->exiting == NULL)
 {
  error(0, "Cannot create new event handle: %s", strerror(errno));
  //panic(0, "Cannot create new event handle.");
 }

 if (ti->wake_handle == NULL)
 {
  error(0, "Cannot create new event handle: %s", strerror(errno));
  //panic(0, "Cannot create new event handle.");
 }
#endif

 
 first_try = next_threadnumber;                 
 do {
  ti->number = next_threadnumber++;         //填充线程序号                
  
  if (ti->number == first_try + THREADTABLE_SIZE)     //用来检测线程序号是否超过THREADTABLE_SIZE
  {
   error(0, "Cannot have more than %d active threads", THREADTABLE_SIZE);
  }
 } while (THREAD(ti->number) != NULL);       //确保该线程号可用,之前无线程
 THREAD(ti->number) = ti;

 active_threads++;                     //总线程数+1
 started_threads ++;

 return ti->number;
}



static struct threadinfo *getthreadinfo(void) {       //获取检查当前运行的线程的线程信息结构
 struct threadinfo *threadinfo = NULL;
#ifndef WIN32
 threadinfo = (struct threadinfo *)pthread_getspecific(tsd_key);   //根据当前运行的线程,设置的线程键tsd_key获取
 if (threadinfo == NULL)
 {
  error(0, "thread-pthread: pthread_getspecific failed: %s", strerror(errno));
 } else
 {
  _assert(pthread_equal(threadinfo->self, pthread_self()));
 }
#else
 long iSelf = GetCurrentThreadId();           //当前线程句柄id
 int  i = 0;

 
 for (i = 0;i < next_threadnumber; i++)         //在当先开始和运行的线程中寻找对应的线程
 {
  if (THREAD(i) == NULL)
   continue;
  if (THREAD(i)->self == iSelf)               //找到线程
   break;
 }

 if (i == next_threadnumber||THREAD(i) == NULL)
  threadinfo = NULL;
 else
  threadinfo = THREAD(i);                      //获得序号i的信息结构体
#endif
 return threadinfo;
}


static void delete_threadinfo(void) {
 struct threadinfo *threadinfo;
#ifdef WIN32
 long lTempNumber = -1;
#endif

 threadinfo = getthreadinfo();                 //从线程信息数组中获取对应所需的信息结构体
 
 if (!threadinfo)
  return ;

#ifndef WIN32      //windows
 pthread_cond_broadcast(&threadinfo->exiting);    //利用退出信号量 广播该线程信息的退出删除 事件
 pthread_cond_destroy(&threadinfo->exiting);      //删除该线程信息结构体的退出信号事件
 close(threadinfo->wakefd_recv);                 //关闭接收和发送管道句柄
 close(threadinfo->wakefd_send);

 THREAD(threadinfo->number) = NULL;                //将该线程信息结构体在数组中的下标位置置为NULL  可用
#else             //linux
 SetEvent(threadinfo->exiting);           //设置退出事件                
 CloseHandle(threadinfo->exiting);        //关闭退出事件句柄

 SetEvent(threadinfo->wake_handle);          //激发叫醒事件
 CloseHandle(threadinfo->wake_handle);       //关闭叫醒事件句柄

 lTempNumber = threadinfo->number;           
#endif
 active_threads--;                         //活跃线程数量减1
 c_assert(threadinfo != &mainthread);
 _free(threadinfo);                         //释放该线程结构体信息
#ifdef WIN32
 THREAD(lTempNumber) = NULL;                 //将该线程信息结构体在数组中的下标位置置为NULL  可用
#endif
}

static void create_threadinfo_main(void) {                     //创建主线程结构体信息
 int ret = 0;

#ifndef WIN32
 fill_threadinfo(pthread_self(), "main", NULL, &mainthread);    //填充主线程结构体信息
 ret = pthread_setspecific(tsd_key, &mainthread);                //制定主线程为线程键
 if (ret != 0)
 {
  error(ret, "thread-pthread: pthread_getspecific failed: %s", strerror(errno));
 }
#else
 fill_threadinfo(GetCurrentThreadId(), "main", NULL, &mainthread);   //填充主线程结构体信息
#endif
}

using namespace clib;
// Added by David, 2000-12-5.
void CThread::delete_threadinfo_main(void) {                   //删除主线程结构体信息
 struct threadinfo *threadinfo;

 threadinfo = getthreadinfo();                             //根据设置的线程键获取  主线程的信息结构体

 if (!threadinfo)
  return;
#ifndef WIN32
 pthread_cond_broadcast(&threadinfo->exiting);               //利用退出信号量 广播主线程信息的退出删除 事件
 pthread_cond_destroy(&threadinfo->exiting);              //删除该线程信息结构体的退出信号事件
 close(threadinfo->wakefd_recv);                              //关闭接收和发送管道句柄
 close(threadinfo->wakefd_send);
#else
 SetEvent(threadinfo->exiting);               //设置退出事件
 CloseHandle(threadinfo->exiting);

 SetEvent(threadinfo->wake_handle);
 CloseHandle(threadinfo->wake_handle);
#endif
 THREAD(threadinfo->number) = NULL;                            //将该线程信息结构体在数组中的下标位置置为NULL  可用
 active_threads--;
// _assert(threadinfo != &mainthread);
// _free(threadinfo);
}

// initilization function 
void CThread::ThreadInit(void)                      //初始化该线程管理类
{
 int ret = 0;
 int i;

 if (iInitilizated++)                             //确保初始化        
  return;

#ifndef WIN32
 if (!threadtable_lock)                              
 {
  threadtable_lock = new pthread_mutex_t;      //如果没锁,则为线程新建一个mutex信号锁threadtable_lock
  if (!threadtable_lock)
   return;
 }

 pthread_mutex_init(threadtable_lock, NULL);         //初始化该信号锁threadtable_lock
#else
 if (!threadtable_lock)
 {
  threadtable_lock = new CRITICAL_SECTION;        //如果没锁,则为线程新建一个CRITICAL_SECTION信号锁threadtable_lock
  if (!threadtable_lock)
   return;
 }
 InitializeCriticalSection(threadtable_lock);
#endif

#ifndef WIN32
 ret = pthread_key_create(&tsd_key, NULL);           //创建初始化线程键tsd_key
 if (ret != 0)
 {
  error(ret, "thread-pthread: pthread_key_create failed: %s", strerror(errno));
 }
#else
 //
#endif

 for (i = 0; i < THREADTABLE_SIZE; i++) {                //将线程信息结构体指针数组全部初始化为空NULL
  threadtable[i] = NULL;
 }
 active_threads = 0;

 create_threadinfo_main();                  //创建主线程mainThread

// lib_protected_init();
}



void CThread::ThreadShutdown(void)               
{
 int ret = 0;
 int running;
 int i;
 static int iShutdowned = 0;

 if (--iInitilizated)                          //确保线程类被杀掉,重置初始
  return;

 
 c_assert(threadtable[0] != NULL);
 lock();
 
 running = 0;
 
 for (i = 1; i < THREADTABLE_SIZE; i++) {             //遍历线程信息结构体指针数组
  if (threadtable[i] != NULL) {
   debug("lib", 0, "Thread %ld (%s) still running",
    threadtable[i]->number,
    threadtable[i]->name);
   running++;                               //确定该线程类中的线程数running
  }
 }
 unlock();           

 
 if (running)              //确保除了主线程外没有其他线程运行
  return;
#ifndef WIN32
 if (!threadtable_lock)
  return;

 ret = pthread_mutex_destroy(threadtable_lock);          //杀掉线程数组的锁         
 if (ret != 0)
 {
  warning(ret, "cannot destroy threadtable lock");
 }

 SAFEDELETE(threadtable_lock);
#else
 if (!threadtable_lock)
  return;

 DeleteCriticalSection(threadtable_lock);
 SAFEDELETE(threadtable_lock);
#endif

 

   //删除主线程信息结构体
// // I must delete main thread information in here, matched with create_threadinfo_main() inside of thread_init()
 delete_threadinfo_main(); // It must be commented in here, because main thread
        // information will be used in later.
}


#ifdef WIN32
static void * __stdcall new_thread(void *arg)
#else
 static void *new_thread(void *arg)
#endif
{
 int ret = 0;
 struct new_thread_args *p = (struct new_thread_args *)arg;     //arg强制转化为new_thread_args *类型

 
 lock();
 unlock();

 
 
#ifndef WIN32
 ret = pthread_setspecific(tsd_key, p->ti);                    //将新创建的线程赋予线程键
 if (ret != 0)
 {
  error(ret, "thread-pthread: pthread_setspecific failed: %s", strerror(errno));
 }
#else
 //
#endif
 (p->func)(p->arg);

 lock();
 debug("lib.thread", 0, "Thread %ld (%s) terminates.",
  p->ti->number, p->ti->name);
 
 _free(p);
 delete_threadinfo();
 unlock();

 return NULL;
}


long CThread::ThreadCreate(thread_func_t *func, void *arg){
 return CThread::thread_create_real(func, "", arg);
}

long CThread::thread_create_real(thread_func_t *func, const char *name, void *arg)
{
 long ret;
#ifndef WIN32
 pthread_t id;                 //线程id
#else
 long id = -1;
#endif
 struct new_thread_args *p;         //线程信息结构体参数
 long number;
 
 
 p = (struct new_thread_args *)_malloc(sizeof(*p));         //动态分配内存
 p->func = func;
 p->arg = arg;
 p->ti = (struct threadinfo *)_malloc(sizeof(*(p->ti)));        //动态分配内存

 
 lock();

 if (active_threads >= THREADTABLE_SIZE) {           //确保线程结构体信息数组数量
  unlock();
  warning(0, "Too many threads, could not create new thread.");
  _free(p);
  return -1;
 }

#ifndef WIN32
 ret = pthread_create(&id, NULL, &new_thread, p);      //以p为传入参数创建线程
 if (ret != 0) {
  unlock();
  error(ret, "Could not create new thread.");
  _free(p);
  return -1;
 }
#else   //以p为传入参数创建线程
 ret = _beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))new_thread, p, 0, (unsigned *)&id);
// ret = _beginthreadex(NULL, 0, new_thread, p, 0, (unsigned *)&id);
 if (ret <=0)
 {
  unlock();
  error(ret, "Could not create new thread.");
  _free(p);
  return -1;
 }
#endif

#ifndef WIN32
 ret = pthread_detach(id);                      
 if (ret != 0) {
  warning(ret, "Could not detach new thread.");
 }
#endif

 number = fill_threadinfo(id, name, func, p->ti);       //填充线程信息结构并保存在信息数组中    
 unlock();

 return number;
}

// wait for single thread to exit, nTimeOut in millionseconds

void CThread::ThreadJoin(long thread, long nTimeOut)  
{
 struct threadinfo *threadinfo;     
#ifndef WIN32
 struct timespec abstime;
     struct timeval now;          //现在的时间
 struct timezone zone;
#endif
 int ret = 0;

 if (thread < 0)
  return;

 lock();
 threadinfo = THREAD(thread);                           //根据下标获得该线程信息结构体
 if (threadinfo == NULL || threadinfo->number != thread) {
  unlock();
  return;
 }

 
#ifndef WIN32
 if (nTimeOut > 0)
  //设定等待时间
  gettimeofday(&now, &zone);
  abstime.tv_sec = now.tv_sec + nTimeOut / 1000;
  abstime.tv_nsec = now.tv_usec * 1000;
  if (!threadtable_lock)
   return;
         //一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。
  ret = pthread_cond_timedwait(&threadinfo->exiting, threadtable_lock, &abstime);   //等待捕获退出信号量
  if (ret == ETIMEDOUT)
  {
           
   if (threadinfo->name != NULL)
    warning(0, "ThreadJoin: thread %s can't stop.", threadinfo->name);

        } else
  {
                     
        }
 }
 else // nTimeOut <= 0, wait infinitely!
 {
  if (!threadtable_lock)
   return;

  ret = pthread_cond_wait(&threadinfo->exiting, threadtable_lock); //等待捕获退出信号量
  if (ret != 0)
  {
   warning(ret, "ThreadJoin: error in pthread_cond_wait");
  }
 }
 unlock();
#else
 if (nTimeOut <= 0)
  nTimeOut = INFINITE;

 unlock(); // Added here because of using WIN32
 if (threadinfo->number != 0)  // don't wait main thread
  if (WaitForSingleObject(threadinfo->exiting, nTimeOut) == WAIT_TIMEOUT)   //等待退出信号事件
  {
   if (threadinfo->name != NULL)
    warning(0, "ThreadJoin: thread %s can't stop.", threadinfo->name);
  }
// ResetEvent(threadinfo->exiting); // pointed by zxm, 2000-11-21
// unlock(); // Commented because of using WIN32
#endif
}


void CThread::ThreadJoinAll(long nTimeOut) {
 long i;
 long our_thread = ThreadSelf();       //当前运行的线程

 for (i = 0; i < THREADTABLE_SIZE; ++i) {
  if (THREAD(our_thread) != THREAD(i))    //如果不是当前运行的线程
   ThreadJoin(i, nTimeOut);             //就退出该线程
 }
}

void CThread::ThreadWakeUpAll(void) {
 long i;
 long our_thread = ThreadSelf();      //当前运行的线程

 for (i = 0; i < THREADTABLE_SIZE; ++i) {
  if (THREAD(our_thread) != THREAD(i))
   ThreadWakeUp(i);       //唤醒所有当前不运行的线程
 }
}

void CThread::ThreadJoinEvery(thread_func_t *func, long nTimeOut)
 {
 long i;
 struct threadinfo *ti;
 int ret = 0;

 lock();
 for (i = 0; i < THREADTABLE_SIZE; ++i) {
  ti = THREAD(i);
  if (ti == NULL || ti->func != func)
   continue;
  debug("lib.thread", 0,
       "Waiting for %ld (%s) to terminate",
   ti->number, ti->name);
#ifndef WIN32
  if (!threadtable_lock)
   return;

  ret = pthread_cond_wait(&ti->exiting, threadtable_lock);
  if (ret != 0) {
   warning(ret, "ThreadJoin_all: error in "
     "pthread_cond_wait");
  }
#else
  unlock();
  WaitForSingleObject(ti->wake_handle, nTimeOut);
//  ResetEvent(ti->wake_handle);
#endif
 }
 unlock();
}



long CThread::ThreadSelf(void) {
 struct threadinfo *threadinfo = NULL;

#ifndef WIN32
 threadinfo = (struct threadinfo *)pthread_getspecific(tsd_key);      //获得当前运行的线程,根据线程键
#else
 int i = 0;
 long lCurrentThreadId = GetCurrentThreadId();               //获得当前运行线程的id

 for (i = 0; i < THREADTABLE_SIZE; ++i)
 {
  if (THREAD(i))
   if (lCurrentThreadId == THREAD(i)->self)                //找到当前线程id所对应的线程信息结构体
    return i;
 }
#endif
 if (threadinfo)
  return threadinfo->number;           //返回其序列号
 else
  return -1;
}

void CThread::ThreadWakeUp(long thread) {
 struct threadinfo *threadinfo;
#ifndef WIN32
 unsigned char c = 0;
 int fd;
#endif

 lock();

 threadinfo = THREAD(thread);                   //根据下标获得对应线程信息结构体
 if (threadinfo == NULL || threadinfo->number != thread) {
  unlock();
  return;
 }

#ifndef WIN32
 fd = threadinfo->wakefd_send;                       //发送管道
 unlock();
 write(fd, &c, 1);                        //发出运行信号
#else
 unlock(); // Found by Zhang Yuan, 2001-2-19.
 SetEvent(threadinfo->wake_handle);              //设置唤醒事件
#endif
}

int CThread::thread_pollfd(int fd, int events, double timeout) {
#ifndef WIN32
 struct pollfd pollfd[2];
 struct threadinfo *threadinfo;
 int milliseconds;
 int ret;

 threadinfo = getthreadinfo();

 pollfd[0].fd = threadinfo->wakefd_recv;
 pollfd[0].events = POLLIN;

 pollfd[1].fd = fd;
 pollfd[1].events = events;

 milliseconds = (int)(timeout * 1000);

 ret = poll(pollfd, 2, milliseconds);
 if (ret < 0) {
  if (errno != EINTR)
   error(errno, "thread_pollfd: error in poll");
  return -1;
 }

 if (pollfd[0].revents)
  flushpipe(pollfd[0].fd);

 return pollfd[1].revents;
#else
 return -1;
#endif
}

int CThread::thread_poll(struct pollfd *fds, long numfds, double timeout) {
#ifndef WIN32
 struct pollfd *pollfds;
 struct threadinfo *threadinfo;
 int milliseconds;
 int ret;

 threadinfo = getthreadinfo();

 

 pollfds = (struct pollfd *)_malloc((numfds + 1) * sizeof(*pollfds));
 pollfds[0].fd = threadinfo->wakefd_recv;
 pollfds[0].events = POLLIN;
 memcpy(pollfds + 1, fds, numfds * sizeof(*pollfds));

 milliseconds = (int)(timeout * 1000);

 ret = poll(pollfds, numfds + 1, milliseconds);
 if (ret < 0) {
  if (errno != EINTR)
   error(errno, "thread_poll: error in poll");
  return -1;
 }
 if (pollfds[0].revents)
  flushpipe(pollfds[0].fd);

       
 memcpy(fds, pollfds + 1, numfds * sizeof(*pollfds));
        _free(pollfds);

 return ret;
#else
 return -1;
#endif
}

//void thread_sleep(double seconds) {
void CThread::ThreadSleep(long nMilliSeconds)
{
#ifndef WIN32
 struct pollfd pollfd;
 int ret;
#endif
 struct threadinfo *threadinfo;

 threadinfo = getthreadinfo();

 if (!threadinfo)
 {
  error(0, "Can not get the current thread information:%s", strerror(errno));
  return;
 }

#ifndef WIN32
 pollfd.fd = threadinfo->wakefd_recv;
 pollfd.events = POLLIN;
#endif

#ifndef WIN32
 ret = poll(&pollfd, 1, nMilliSeconds);
 if (ret < 0) {
  if (errno != EINTR && errno != EAGAIN) {
   warning(errno, "thread_sleep: error in poll");
  }
 }
 if (ret == 1) {
  flushpipe(pollfd.fd);
 }
#else
 WaitForSingleObject(threadinfo->wake_handle, nMilliSeconds);
// ResetEvent(threadinfo->wake_handle);
#endif
}

#ifdef WIN32

#undef FUNC_NAME
#define FUNC_NAME(x) #x
int CThread::thread_fill_threadinfo(thread_func_t *func, long id)
{
 struct threadinfo *ti = NULL;
 long number = -1;

 ti = (struct threadinfo *)_malloc(sizeof(*ti));

 
 lock();

 if (active_threads >= THREADTABLE_SIZE)
 {
  unlock();
  warning(0, "Too many threads, could not create new thread.");
  _free(ti);
  return -1;
 }

 number = fill_threadinfo(id, FUNC_NAME(func), func, ti);
 unlock();

 return number;
}

int CThread::thread_delete_threadinfo(void)
{
 struct threadinfo *threadinfo;
 long lTempNumber = -1;


 threadinfo = getthreadinfo();

 SetEvent(threadinfo->exiting);
 CloseHandle(threadinfo->exiting);

 SetEvent(threadinfo->wake_handle);
 CloseHandle(threadinfo->wake_handle);

 lTempNumber = threadinfo->number;

 active_threads--;
 c_assert(threadinfo != &mainthread);
 _free(threadinfo);

 THREAD(lTempNumber) = NULL;

 return 0;
}

#endif


long CThread::RunningThreadNumber(void)
{
 return active_threads;
}


long CThread::StartedThreadNumber(void)
{
 return started_threads;
}




char* CThread::GetThreadInfo(long &nSize)
{
 static char tempBuffer[MAX_PATH];
 char *p = NULL;
 
 if (nSize < 0 || nSize >= THREADTABLE_SIZE)
  return NULL;

 if (THREAD(nSize))
 {
  p = strrchr(THREAD(nSize)->name, ':');

  sprintf(tempBuffer, "%d:%s", THREAD(nSize)->self, p ? p + 1 : THREAD(nSize)->name);
 }
 else
  return NULL;
 
 nSize ++;

 return tempBuffer;
}


//
// Construction/Destruction
//

CThread::CThread()
{
 
}

CThread::~CThread()
{
 
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值