线程类封装(2)

 

threadImpl.hpp


#ifndef THREAD_THREADIMPL_HPP_
#define THREAD_THREADIMPL_HPP_


// #include <standard library headers>

// #include <other library headers>
#ifdef _WIN32
#include <Windows.h>
#include <process.h>
#else
#include <pthread.h>
#include <unistd.h>
#endif

// #include "customer headers"


namespace thread
{

    class ThreadImpl
    {
    public:
#ifdef _WIN32
        struct ThreadStruct
        {
            HANDLE ht;
            unsigned int tid;
            ThreadStruct() : ht(NULL), tid(INVALID_THREAD_ID) {}
            void Cleanup();
            ~ThreadStruct() { Cleanup(); }
        };
        typedef unsigned int (__stdcall *ThreadFuncT)(void* param);
#else
        struct ThreadStruct
        {
            pthread_t pt;
            ThreadStruct() : pt(0) {}
            void Cleanup() { pt = 0; }
            ~ThreadStruct() { Cleanup(); }
        };
        typedef void* (*ThreadFuncT)(void* param);
#endif

    private:
        ThreadImpl();
        ThreadImpl(const ThreadImpl&) throw();
        void operator=(const ThreadImpl&);

    public:
        static bool Create(ThreadStruct& ts, ThreadFuncT func, void* arg);
        static void Destroy(ThreadStruct& ts) { ts.Cleanup(); }
        static bool WaitForEnd(const ThreadStruct& ts, int ms);
        static void Terminate(const ThreadStruct& ts);
        static bool IsAlive(const ThreadStruct& ts);
        static int GetId(const ThreadStruct& ts);
        static void Sleep(int ms);

    public:
#if _MSC_VER < 1400 // < vc8
        enum { WAIT_INFINITE = -1 };
        enum { INVALID_THREAD_ID = 0 };
        enum { WAIT_TIME_SLICE = 20 };
#else
        static const int WAIT_INFINITE = -1;
        static const int INVALID_THREAD_ID = 0;
        static const int WAIT_TIME_SLICE = 20;
#endif
    };


#ifdef _WIN32

    inline void ThreadImpl::ThreadStruct::Cleanup()
    {
        if (ht != NULL)
        {
            CloseHandle(ht);
            ht = NULL;
        }
        tid = INVALID_THREAD_ID;
    }

    inline bool ThreadImpl::Create(ThreadStruct& ts, ThreadFuncT func,
                                   void* arg)
    {
        ts.ht = (HANDLE)_beginthreadex(NULL, 0, func, arg, 0, &ts.tid);
        return (ts.ht != NULL);
    }

    inline bool ThreadImpl::WaitForEnd(const ThreadStruct& ts, int ms)
    {
        DWORD to = (DWORD)ms;
        if(ms == WAIT_INFINITE)
        {
            to = INFINITE;
        }
        DWORD res = WaitForSingleObject(ts.ht, to);
        return (res != WAIT_TIMEOUT);
    }

    inline void ThreadImpl::Terminate(const ThreadStruct& ts)
    {
        ::TerminateThread(ts.ht, 0);
    }

    inline bool ThreadImpl::IsAlive(const ThreadStruct& ts)
    {
        if (ts.ht == NULL)
        {
            return false;
        }
        DWORD res = WaitForSingleObject(ts.ht, 0);
        return (WAIT_TIMEOUT == res);
    }

    inline int ThreadImpl::GetId(const ThreadStruct& ts)
    {
        return (int)ts.tid;
    }

    inline void ThreadImpl::Sleep(int ms)
    {
        ::Sleep(ms);
    }

#else

    inline bool ThreadImpl::Create(ThreadStruct& ts, ThreadFuncT func,
                                   void* arg)
    {
        int res = pthread_create(&(ts.pt), NULL, func, arg);
        if (res != 0)
        {
            return false;
        }
        pthread_detach(ts.pt);
        return true;
    }

    inline bool ThreadImpl::WaitForEnd(const ThreadStruct& ts, int ms)
    {
        int iDelta = WAIT_TIME_SLICE;
        int iTotal = ms;
        if (ms == WAIT_INFINITE)
        {
            iDelta = 0;
            iTotal = 1;
        }
        for (int i = 0; i < iTotal; i += iDelta)
        {
            if (!IsAlive(ts))
            {
                return true;
            }
            else
            {
                ThreadImpl::Sleep(WAIT_TIME_SLICE);
            }
        }
        return false;
    }

    inline void ThreadImpl::Terminate(const ThreadStruct& ts)
    {
        ::pthread_cancel(ts.pt);
    }

    inline bool ThreadImpl::IsAlive(const ThreadStruct& ts)
    {
        if (ts.pt == 0)
        {
            return false;
        }

        int policy;
        struct sched_param sp;
        // in linux, pthread_getschedparam may SIGSEGV when tid is invalid.
        int res = pthread_getschedparam(ts.pt, &policy, &sp);
        return (res == 0);
    }

    inline int ThreadImpl::GetId(const ThreadStruct& ts)
    {
        return (int)ts.pt;
    }

    inline void ThreadImpl::Sleep(int ms)
    {
        int s = ms / 1000;
        int us = (ms % 1000) * 1000;
        if (s > 0)
        {
            sleep(s);
        }
        if (us > 0)
        {
            usleep(us);
        }
    }

#endif // _WIN32

}


#endif // THREAD_THREADIMPL_HPP_

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值