创建多线程

//ThreadHelper.h

/*--License(在这里设置版权或许可等信息)
--自由无限制
*/

/*
\-Version(在这里记录版本等信息)
--1.00
--publish from http://www.loveunix.net(非正式发布)
--V1.00_@2004_??_?? by somebody(a.somebody@gmail.com).
--update@2005_06_01 by someone.
*/

/*
\        brief(在这里做功能简介)
        (Wrapper Thread && ThreadPool)
        Thread(class)线程包装(线程类/通过非静态类成员函数创建线程等)
        ThreadPool(class)线程池
*/

/*
\        misc(在这里添加使用帮助说明或补充其他细节)
        VC++ 6.0(Win2k ADS)
        GCC(g++) 3.3.2(Red Hat Linux 7.2)
        VC++ 7.1(VS 2003.NET)(Win2k ADS)
        Compiled good(run ok).
*/

//#include "ThreadHelper.h"
#ifndef _THREAD_HELPER_H__
#define _THREAD_HELPER_H__

#define        DEF_THREADHELPER
#if(0)
//class ThreadHelper {};//--null
#endif

//--WIN32
#if        !defined(WIN32)
#if defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
#define        WIN32
#endif
#endif

//--LINUX
#if        !defined(WIN32) && !defined(LINUX)
#define        LINUX
#endif

#if        !defined(WIN32) && !defined(LINUX)
#error        only Support Win32 or Linux.
#endif

#ifdef        WIN32
#include <windows.h>
#include <string.h>
#endif

#ifdef        LINUX
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#endif

#ifndef        NULL
#define        NULL        0
#endif

//--class Declare
class Thread;
class ThreadPool;
//
//--Thread Base class
class ThreadBase { public: typedef void* (ThreadBase::*Entry)(void*); };
typedef ThreadBase::Entry ThreadBaseEntry;
//
template <typename T>
class ThreadTemplate
{
        friend class Thread;
        friend class ThreadWrapper;
private:
        typedef void* (T::*Entry)(void*);
        T*                pClass;        //--Thread Class
        void*        pData;        //--传递给线程的参数
        Entry        pEntry;        //--Thread Entry Ptr

public:
        ThreadTemplate<T>()
                : pClass(0), pEntry(0), pData(0)
                , Result(0)
                , handle(0), ThreadId(0)
        {};
        long        Result;        //--保存线程返回值

        //--保留与系统相关的线程数据
#if defined(WIN32)
        //--WIN32
        HANDLE        handle;
        DWORD        ThreadId;
#elif defined(LINUX)
        //--LINUX
        pthread_t ThreadId;
        int handle;
#else
#pragma message( "--unsupported--" )
#endif
};
//
typedef ThreadTemplate<ThreadBase>        ThreadObject;
typedef ThreadObject*        ThreadObjectPtr;
//
//--ThreadWrapper
//--线程包装
class ThreadWrapper
{
        friend class Thread;
private:
        void __CreateAny();//--null
        //--创建线程
        //--线程入口(任意类函数)
        template<typename T>
                ThreadObjectPtr CreateAny(T * pClass, ThreadBaseEntry pEntry, void* pData)
        {
                ThreadObjectPtr pThread = new ThreadObject;
                pThread->pClass        = (ThreadBase*)pClass;
                pThread->pData        = pData;
                pThread->pEntry        = pEntry;
                return CreateWrapper(NULL, NULL, pThread);
        }

        //--ThreadCreate
        //--模板函数
        template<typename T>
                ThreadObjectPtr ThreadCreate(T* pClass
#if        defined(_MSC_VER) && (_MSC_VER >= 1300)
                , ThreadTemplate<Thread>::Entry pEntry//--VC7
#else
                , ThreadTemplate<T>::Entry pEntry
#endif
                , void* pData = NULL
                )
        { 
                if (NULL == pClass || NULL == pEntry) return NULL;

                //--创建暂存对象(ThreadTemplate<T>/ThreadObject)
                //--注意这个对象由(Thread)删除
                ThreadTemplate<T> * pObj = new ThreadTemplate<T>;

                //--设置参数
                pObj->pEntry        = pEntry;
                pObj->pClass        = pClass;
                pObj->pData                = pData;

                //--创建线程
                return CreateWrapper(NULL, NULL, pObj);
        }

        //--EntryWrapper(线程入口)
        //--包装线程入口(类函数)
        static void EntryWrapper(ThreadObjectPtr pThread)
        {
                if (NULL == pThread) return;
                long Result = 0;

                //--这里执行真正的线程代码
                Result = (long)(pThread->pClass->*(pThread->pEntry))(pThread->pData);
                //--真正的线程代码执行完毕(线程马上退出)

                //--Result
                pThread->Result = Result;
        }

        //--EntryEntry(线程入口)
        //--包装线程入口(普通函数)
        struct EntryData
        {
                ThreadObjectPtr pThread;//--Result
                void* pData;
                void* pEntry;
        };
        static void EntryEntry(EntryData * pEntry)
        {
                if (NULL == pEntry) return;
                long Result = 0;

                //--这里执行真正的线程代码
                typedef long (*ENTRY)(void*);
                ENTRY entry = (ENTRY)pEntry->pEntry;
                if (entry) Result = (long)( (*entry)(pEntry->pData) );
                //--真正的线程代码执行完毕(线程马上退出)

                //--Result
                if (NULL != pEntry->pThread) pEntry->pThread->Result = Result;
                delete pEntry;
        }

        //--CreateWrapper(创建并运行线程)
        //--以(EntryWrapper)或(EntryEntry)做线程入口
        static ThreadObjectPtr CreateWrapper(void* entry, void* pData, void* pObj = NULL);
};
inline
ThreadObjectPtr ThreadWrapper::CreateWrapper(void* entry, void* pData, void* pObj)
{
        ThreadObjectPtr pThread = NULL;
        EntryData * pEntryData = NULL;
        if (NULL == pObj)
        {
                pThread = new ThreadObject;

                pEntryData = new EntryData;
                pEntryData->pThread        = pThread;
                pEntryData->pEntry        = entry;
                pEntryData->pData        = pData;
        }
        else pThread = ThreadObjectPtr(pObj);
        //--在这里调用系统代码
        if (NULL != pThread)
        {
#ifdef        WIN32
                //--WIN32
#pragma message( "WIN32 ThreadWrapper::CreateThreadWrapper" )
                typedef LPTHREAD_START_ROUTINE        ThreadEntry;
                pThread->ThreadId = 0;
                pThread->handle = NULL;
                pThread->handle = CreateThread(NULL, 0
                        , ( (NULL == pObj)
                        ?( (ThreadEntry)EntryEntry )
                        :( (ThreadEntry)EntryWrapper ) )
                        , ( (NULL == pObj)?( (void*)pEntryData):( (void*)pThread) )
                        , 0, &pThread->ThreadId);
#elif        defined(LINUX)
                //--LINUX
#pragma message( "LINUX ThreadWrapper::CreateThreadWrapper" )
                typedef void* (*ThreadEntry)(void*);
                pThread->ThreadId = 0;
                pThread->handle = 0;
                pThread->handle = pthread_create(&pThread->ThreadId, NULL
                        , ( (NULL == pObj)
                        ?( (ThreadEntry)EntryEntry )
                        :( (ThreadEntry)EntryWrapper ) )
                        , ( (NULL == pObj)?( (void*)pEntryData):( (void*)pThread) )
                        );
#else
#pragma message( "--unsupported--" )
#endif
        }
        return pThread;
}
//
//--Thread
//--线程(包装)类(实现通过类非静态成员函数创建线程等)
class Thread
{
public:
        //--(线程函数)默认线程入口(类非静态成员函数)
        virtual void* ThreadProc(void* pData = NULL) { return 0; };

public:
        //--睡眠(ms)毫秒
        static void Sleep(int ms);

        //--结束线程(强制杀掉线程)
        //--成功返回0
        int Kill(ThreadObjectPtr pThread = NULL);
        //--等待线程(线程结束返回)
        //--成功返回0
        int Wait(ThreadObjectPtr pThread = NULL);

        //--获取线程(ThreadObject)数据
        //--返回(ThreadObject/线程数据对象)指针(成功)或0(失败)
        inline ThreadObjectPtr GetThread() const { return PtrThreadObject; };

public:
        void __CreateAny();//--null
        //--Create(创建并运行线程)
        //--线程入口 = pEntry
        //--pEntry(任意类任意成员函数)
        //--要求任意类任意成员函数原型(参数与返回值类型)为[void* (void*)]/不保证其他原型不出错
        //--需要参数(tClass)
        //--tClass(pEntry宿主类)
        //--返回(ThreadObject/线程数据对象)指针
        template<typename T>
        ThreadObjectPtr Create(T & tClass, ThreadBaseEntry pEntry, void* pData)
        {
                ThreadWrapper        Wrapper;
                ThreadInit();
                SetThread(
                        Wrapper.CreateAny(&tClass, pEntry, pData)
                        );
                delay();
                return GetThread();
        }

public:
        //--Create(创建并运行线程)
        //--线程入口 = ThreadProc
        //--ThreadProc(线程函数)默认线程入口(类非静态成员函数)
        //--返回(ThreadObject/线程数据对象)指针
        ThreadObjectPtr Create(void* pData)
        {
                ThreadWrapper        Wrapper;
                ThreadInit();
                SetThread(
                        Wrapper.ThreadCreate(this
                        , (ThreadTemplate<Thread>::Entry)&Thread::ThreadProc
                        , pData)
                        );
                delay();
                return GetThread();
        }
        //--Create(创建并运行线程)
        //--线程入口 = entry
        //--entry(普通函数/或类静态成员函数)
        //--返回(ThreadObject/线程数据对象)指针
        ThreadObjectPtr Create(void* entry, void* pData)
        {
                ThreadWrapper wrapper;
                ThreadInit();
                SetThread(
                        wrapper.CreateWrapper(entry, pData)
                        );
                delay();
                return GetThread();
        }

public:
        Thread() : PtrThreadObject(NULL) {};
        virtual ~Thread() { ThreadInit(); };
        //inline ThreadObjectPtr GetThread() const { return PtrThreadObject; };
private:
        inline void SetThread(ThreadObjectPtr v) { PtrThreadObject = v; };
        //--data
        ThreadObjectPtr        PtrThreadObject;
        //--初始化或结束
        void ThreadInit()
        {
                ThreadObjectRelease(PtrThreadObject);
                clear();
        }
protected:
        void clear() { PtrThreadObject = NULL; };
        //--清空并释放(删除)(ThreadObject)对象
        void ThreadObjectRelease(ThreadObjectPtr p)
        {
                if (NULL == p) return;
#if defined(WIN32)
                if (p->handle) CloseHandle(p->handle);
#endif
                memset(p, 0, sizeof(*p));
                delete p;
        }
        //--通过调用(delay)让当前线程交出控制权
        //--阻止当前线程独占资源
        //--当前线程会被挂起约一毫秒的时间
        static void delay()
        {
                Thread::Sleep(0);
                Thread::Sleep(1);
                Thread::Sleep(0);
        }
};
inline int Thread::Kill(ThreadObjectPtr pThread)
{
        int ret = 0;
        const ThreadObjectPtr a = (NULL != pThread)?(pThread):(GetThread());
        //--这里调用操作系统相关的代码
        if (NULL != a)
        {
#if defined(WIN32)
                //--WIN32
#pragma message( "WIN32 Thread::Kill" )
                HANDLE handle = a->handle;
                if (NULL != handle)
                {
                        BOOL b = TerminateThread(handle, 0);
                        //--FAILED
                        if (!b) ret = b;
                        CloseHandle(handle);
                        a->handle = NULL;
                }
#elif defined(LINUX)
                //--LINUX
#pragma message( "LINUX Thread::Kill" )
                pthread_t ThreadId = a->ThreadId;
                if (ThreadId > 0)
                {
                        int n = pthread_cancel(ThreadId);
                        //--FAILED
                        if (n) ret = n;
                }
#else
#pragma message( "--unsupported--" )
#endif
                //Wait(a);
        }

        return ret;
}
inline int Thread::Wait(ThreadObjectPtr pThread)
{
        int ret = 0;
        const ThreadObjectPtr a = (NULL != pThread)?(pThread):(GetThread());
        //--这里调用操作系统相关的代码
        if (NULL != a)
        {
#if defined(WIN32)
                //--WIN32
#pragma message( "WIN32 Thread::Wait" )
                HANDLE handle = a->handle;
                if (NULL != handle)
                {
                        DWORD d = WaitForSingleObject(handle, INFINITE);
                        //--FAILED
                        if (WAIT_OBJECT_0 != d) ret = d;
                        if (0 == ret) CloseHandle(handle);
                        a->handle = NULL;
                }
#elif defined(LINUX)
                //--LINUX
#pragma message( "LINUX Thread::Wait" )
                pthread_t ThreadId = a->ThreadId;
                if (ThreadId > 0)
                {
                        int n = pthread_join(ThreadId, NULL);
                        //--FAILED
                        if (0 == n) ret = n;
                }
#else
#pragma message( "--unsupported--" )
#endif
        }
        return ret;
}
inline void Thread::Sleep(int ms)
{
#if defined(WIN32)
        //--WIN32
#pragma message( "WIN32 Thread::Sleep" )
        ::Sleep(ms);
#elif defined(LINUX)
        //--LINUX
#pragma message( "LINUX Thread::Sleep" )
        usleep(ms*1000);
#else
#pragma message( "--unsupported--" )
#endif
}
//--就差线程池了
//
//--ThreadPool
//--线程池
class ThreadPool : public Thread
{
public:
        //--启动线程池内线程
        //--(n > 0) 时先设置线程数(n)再启动线程池内线程
        //--(n <= 512)
        void Start(void* pData)
        {
                if (ThreadNumber <= 0) return;
                ThreadArray = (ThreadObjectPtr*)new ThreadObjectPtr[ThreadNumber];
                for (int i = 0; i < ThreadNumber; ++i)
                {
                        ThreadArray[i] = Create(pData);
                        clear();
                }
        }
        void Start(void* entry, void* pData)
        {
                if (ThreadNumber <= 0) return;
                ThreadArray = (ThreadObjectPtr*)new ThreadObjectPtr[ThreadNumber];
                for (int i = 0; i < ThreadNumber; ++i)
                {
                        ThreadArray[i] = Create(entry, pData);
                        clear();
                }
        }

        //--等待线程池内全部线程结束
        //--成功返回0
        int WaitFor();

        //--获取线程池最大线程数
        int GetNumber() { return ThreadNumber; };
        //--设置线程池最大线程数
        void SetNumber(int n)
        {
                PoolRelease();
                //--一下启动太多线程有可能把系统搞死
                //--限制一下(512/可以根据需要和系统情况自己设置)
                ThreadNumber = (n > 512)?(512):(n);
        }

        //--获取线程池内第(n)(n >=0 && n < ThreadNumber)个线程
        inline ThreadObjectPtr GetThread(int n) const
        {
                if (NULL == ThreadArray) return NULL;
                if (n >= 0 && n < ThreadNumber) return ThreadArray[n];
                return NULL;
        }

public:
        virtual ~ThreadPool() { PoolRelease(); };
        ThreadPool(int n = 1)
                : ThreadArray(0)
                , ThreadNumber(n)
        {};
private:
        int ThreadNumber;//--保存线程数
        ThreadObjectPtr* ThreadArray;//--(内部)线程对象(数组)
        //--初始化或结束
        //--释放对象(内部)
        void PoolRelease()
        {
                if (NULL == ThreadArray) return;
               
                for (int i = 0; i < ThreadNumber; ++i)
                {
                        if (NULL != ThreadArray[i])
                        {
                                ThreadObjectRelease(ThreadArray[i]);
                                ThreadArray[i] = NULL;
                        }
                }
               
                delete []ThreadArray;
                ThreadArray = NULL;
                ThreadNumber = 0;
        }
};
inline int ThreadPool::WaitFor()
{
        int ret = 0;
       
#if defined(WIN32)
        //--WIN32
#pragma message( "WIN32 ThreadPool::WaitFor" )
        if (ThreadNumber > 0 && NULL != ThreadArray)
        {
                if (ThreadNumber <= MAXIMUM_WAIT_OBJECTS)
                {
                        int ii = 0;
                        HANDLE* lpHandles = new HANDLE[ThreadNumber];
                        int i = 0;
                        for (i = 0; i < ThreadNumber; ++i)
                        {
                                if (ThreadArray[i]->handle)
                                        lpHandles[ii++] = ThreadArray[i]->handle;
                        }
                       
                        DWORD d = WaitForMultipleObjects(ii, lpHandles, TRUE, INFINITE);
                        if(WAIT_FAILED == d) ret = d;

                        for (i = 0; i < ii; ++i) CloseHandle(lpHandles[i]);
                        for (i = 0; i < ThreadNumber; ++i)
                        {
                                if (ThreadArray[i]->handle)
                                        ThreadArray[i]->handle = NULL;
                        }

                        delete []lpHandles;
                }
                else
                {
                        int n = MAXIMUM_WAIT_OBJECTS;
                        int m = ThreadNumber/n;
                        int t = n;
                        for (int j = 0; j < m; ++j)
                        {
                                int ii = 0;
                                HANDLE* lpHandles = new HANDLE[t];
                                int i = 0;
                                for (i = 0; i < t; ++i)
                                {
                                        if (ThreadArray[n*j + i]->handle)
                                                lpHandles[ii++] = ThreadArray[n*j + i]->handle;
                                }
                               
                                DWORD d = WaitForMultipleObjects(ii, lpHandles, TRUE, INFINITE);
                                if(WAIT_FAILED == d) ret = d;

                                for (i = 0; i < ii; ++i) CloseHandle(lpHandles[i]);
                                for (i = 0; i < t; ++i)
                                {
                                        if (ThreadArray[n*j + i]->handle)
                                                ThreadArray[n*j + i]->handle = NULL;
                                }

                                delete []lpHandles;
                        }
                        t = ThreadNumber%n;
                        if (t > 0)
                        {
                                int ii = 0;
                                HANDLE* lpHandles = new HANDLE[t];
                                int i = 0;
                                for (i = 0; i < t; ++i)
                                {
                                        if (ThreadArray[n*m + i]->handle)
                                                lpHandles[ii++] = ThreadArray[n*m + i]->handle;
                                }
                               
                                DWORD d = WaitForMultipleObjects(ii, lpHandles, TRUE, INFINITE);
                                if(WAIT_FAILED == d) ret = d;

                                for (i = 0; i < ii; ++i) CloseHandle(lpHandles[i]);
                                for (i = 0; i < t; ++i)
                                {
                                        if (ThreadArray[n*m + i]->handle)
                                                ThreadArray[n*m + i]->handle = NULL;
                                }
                               
                                delete []lpHandles;
                        }
                }
        }
#elif defined(LINUX)
        //--LINUX
#pragma message( "LINUX ThreadPool::WaitFor" )
        if (ThreadNumber > 0 && NULL != ThreadArray)
        {
                pthread_t* pHandles = new pthread_t[ThreadNumber];
                for (int i = 0; i < ThreadNumber; ++i)
                        pHandles[i] = ThreadArray[i]->ThreadId;

                for(int j = 0; j < ThreadNumber; ++j)
                        pthread_join(pHandles[j], NULL);
        }
#else
#pragma message( "--unsupported--" )
#endif
       
        return ret;
}
//

#endif        //--_THREAD_HELPER_H__

 

//--this is only a demo
/*
        --test on--
        VC++ 6.0(Win2k ADS)
        g++ (GCC) 3.3.2(Red Hat Linux 7.2)
        VC++ 7.1(VS 2003.NET)(Win2k ADS)
        Compiled good(run ok).
*/

#include "ThreadHelper.h"
#include <iostream>
using namespace std;
//
//--普通函数创建线程
//
//--普通函数(abc)
int abc(int n)
{
        cout << "::abc" << endl;
        for (int i = 0; i < 5; ++i)
        {
                cout << (1 + i) << endl;
                Thread::Sleep(10);
        }
        cout << "return " << n << endl;
        return (n);
}
//--普通函数(abc2)
void abc2()
{
        cout << "::abc2" << endl;
}
void Thread_Create()
{
        cout << "--go--Thread_Create" << endl;

        Thread thread;
        //--创建线程
        thread.Create((void*)abc, reinterpret_cast<void*>(123) );

        ThreadObjectPtr pt = thread.GetThread();
        cout << "Result = " << pt->Result << endl;
        cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
        cout << "Result = " << pt->Result << endl;

        cout << "--ko--Thread_Create" << endl;
}
void Thread_Create2()
{
        cout << "--go--Thread_Create2" << endl;

        Thread thread;
        //--创建线程
        thread.Create((void*)abc2, NULL );

        ThreadObjectPtr pt = thread.GetThread();
        cout << "Result = " << pt->Result << endl;
        cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
        cout << "Result = " << pt->Result << endl;

        cout << "--ko--Thread_Create2" << endl;
}
//
//--普通类非静态成员函数创建线程
//
//--线程类(A)
//--继承自(Thread)
class A : public Thread
{
        //--(线程函数)默认线程入口(类非静态成员函数)
        virtual void* ThreadProc(void* pData = NULL)
        {
                cout << "A::" << endl;
                for (int i = 0; i < 5; ++i)
                {
                        cout << (1 + i) << endl;
                        Sleep(100);
                }
                return pData;
        }
public:
        //--(线程函数)任意入口(类非静态成员函数)
        void* abc(void* pData = NULL)
        {
                cout << "A::abc" << endl;
                cout << "k = " << k << endl;
                for (int i = 0; i < 5; ++i)
                {
                        cout << (1 + i) << endl;
                        Sleep(100);
                }
                return pData;
        }
        void* abc2(void* pData = NULL)
        {
                cout << "A::abc2" << endl;
                cout << "k = " << k << endl;
                for (int i = 0; i < 5; ++i)
                {
                        cout << (1 + i) << endl;
                        Sleep(100);
                }
                for (int j = 0; j < 5; ++j)
                {
                        cout << (1 + j) << endl;
                        Sleep(100);
                }
                return pData;
        }
        int k;
};
void Thread_A()
{
        cout << "--go--Thread_A" << endl;

        A a;
        A & thread = a;
        //--创建线程
        a.Create((void*)123);

        ThreadObjectPtr pt = thread.GetThread();
        cout << "Result = " << pt->Result << endl;
        cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
        cout << "Result = " << pt->Result << endl;

        cout << "--ko--Thread_A" << endl;
}
void Thread_A2()
{
        cout << "--go--Thread_A2" << endl;

        A a;
        A & thread = a;
        //--创建线程
        a.k = 111;
        a.Create(a, (ThreadBaseEntry)&A::abc, (void*)234);
        ThreadObject t1 = *thread.GetThread();
        a.k = 123;
        a.Create(a, (ThreadBaseEntry)&A::abc2, (void*)100);
        ThreadObject t2 = *thread.GetThread();
        a.k = 300;
        a.Create(a, (ThreadBaseEntry)&A::abc, (void*)258);
        ThreadObject t3 = *thread.GetThread();

        ThreadObjectPtr pt = thread.GetThread();
        cout << "Result = " << pt->Result << endl;
        cout << "Wait()..." << thread.Wait() << endl;//--等待线程结束
        cout << "Result = " << pt->Result << endl;

        cout << "Wait(1)..." << thread.Wait(&t1) << endl;
        cout << "Wait(2)..." << thread.Wait(&t2) << endl;
        cout << "Wait(3)..." << thread.Wait(&t3) << endl;

        cout << "--ko--Thread_A2" << endl;
}
//
//--线程池
//
class B : public ThreadPool
{
        virtual void* ThreadProc(void* pData = NULL)
        {
                cout << "B::" << endl;
                for (int i = 0; i < 5; ++i)
                {
                        cout << (1 + i) << endl;
                        Sleep(100);
                }
                return pData;
        }
public:
};
void ThreadPool_B()
{
        cout << "--go--ThreadPool_B" << endl;

        B b;
        b.SetNumber(3);
        b.Start((void*)777);
        b.Start(abc, (void*)777);
        B & thread = b;

        ThreadObjectPtr pt = thread.GetThread(0);
        thread.Kill(pt);

        cout << "Result = " << pt->Result << endl;
        cout << "WaitFor()..." << thread.WaitFor() << endl;
        cout << "Result = " << pt->Result << endl;

        pt = thread.GetThread(1);
        cout << "Result = " << pt->Result << endl;

        cout << "--ko--ThreadPool_B" << endl;
}
//
//
int main(int argc, char* argv[])
{
        //Thread_Create();
        //Thread_Create2();
        Thread_A();
        Thread_A2();
        //ThreadPool_B();

        cout << endl;
        cout << "wait return ...";
        cout << endl;
        cin.get();
        return 0;
}

 

原帖链接:http://www.loveunix.net/thread-52904-1-1.html

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值