• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    5年前 (2013-06-15)  Socket library |   2 条评论  13 
    文章评分 0 次,平均分 0.0

    Thread 类是一个基类,自定义线程都需要派生自该基类,并且重写Run这个纯虚函数。该类其中有4个数据成员

    	bool m_running;
    	bool m_release;
    	bool m_b_delete_on_exit;
    	bool m_b_destructor;

    m_running标记线程是否在运行(构造函数初始化为true),如果创建线程失败则更改状态为false,析构函数也会更改为false。
    m_release标记是否释放了线程的控制,如果已经释放则线程函数可以运行,否则线程函数需要等待控制被释放。
    m_b_delete_on_exit标记在线程函数执行完毕退出时是否释放该线程资源,如果不释放则该线程还可以重新运行。
    m_b_destructor标记该线程对象是否已经被析构。

    由于pthread_create参数中的线程函数,必须在编译阶段就已经能够确定地址,所以不能是类的非static成员函数。故使用了静态函数StartThread。该函数中会检测是否已经释放了控制权(如果已经释放控制权则线程可以进入真正的线程运行函数),在线程函数执行完毕后会进行状态更新与是否进行资源释放检测。另外StartThread中还有一个比较重要的地方就是参数:

    将对象的指针做为参数传入则可以对虚函数Run实现多态调用.

    #ifndef _SOCKETS_Thread_H
    #define _SOCKETS_Thread_H
    
    #include "sockets-config.h"
    #ifdef _WIN32
    #else
    #include <pthread.h>
    #endif
    #include "Semaphore.h"
    
    #ifdef SOCKETS_NAMESPACE
    namespace SOCKETS_NAMESPACE {
    #endif
    
    #ifdef _WIN32
    // to be
    //typedef DWORD  threadfunc_t;
    //typedef LPVOID threadparam_t;
    //#define STDPREFIX WINAPI
    typedef unsigned threadfunc_t;
    typedef void * threadparam_t;
    #define STDPREFIX __stdcall
    #else
    
    typedef void * threadfunc_t;
    typedef void * threadparam_t;
    #define STDPREFIX
    #endif
    
    
    class Thread
    {
    public:
    	Thread(bool release = true);
    	virtual ~Thread();
    
    	static threadfunc_t STDPREFIX StartThread(threadparam_t);
    
    	virtual void Run() = 0;
    
    #ifdef _WIN32
    	HANDLE GetThread() { return m_thread; }
    	unsigned GetThreadId() { return m_dwThreadId; }
    #else
    	pthread_t GetThread() { return m_thread; }
    #endif
    
    	bool IsRunning();
    	void SetRunning(bool x);
    	bool IsReleased();
    	void SetRelease(bool x);
    	bool DeleteOnExit();
    	void SetDeleteOnExit(bool x = true);
    	bool IsDestructor();
    
    	void Start() {
    		SetRelease(true);
    	}
    
    	void Stop() {
    		Start();
    		SetRunning(false);
    	}
    
    	void Wait();
    
    protected:
    #ifdef _WIN32
    	HANDLE m_thread;
    	unsigned m_dwThreadId;
    #else
    	pthread_t m_thread;
    	pthread_attr_t m_attr;
    #endif
    
    private:
    	Thread(const Thread& ) {}
    	Thread& operator=(const Thread& ) { return *this; }
    	Semaphore m_sem;
    	bool m_running;
    	bool m_release;
    	bool m_b_delete_on_exit;
    	bool m_b_destructor;
    };
    
    
    #ifdef SOCKETS_NAMESPACE
    }
    #endif
    
    #endif // _SOCKETS_Thread_H
    
    

    #include <stdio.h>
    #ifdef _WIN32
    #include <process.h>
    #include "socket_include.h"
    #else
    #include <unistd.h>
    #endif
    
    #include "Thread.h"
    #include "Utility.h"
    
    
    #ifdef SOCKETS_NAMESPACE
    namespace SOCKETS_NAMESPACE {
    #endif
    
    
    Thread::Thread(bool release)
    :m_thread(0)
    ,m_running(true)
    ,m_release(false)
    ,m_b_delete_on_exit(false)
    ,m_b_destructor(false)
    {
    #ifdef _WIN32
    //	m_thread = ::CreateThread(NULL, 0, StartThread, this, 0, &m_dwThreadId);
    	m_thread = (HANDLE)_beginthreadex(NULL, 0, &StartThread, this, 0, &m_dwThreadId);
    #else
    	pthread_attr_init(&m_attr);
    	//设置为detache属性,则该线程退出时自己释放资源而不是创建线程来释放。
    	pthread_attr_setdetachstate(&m_attr,PTHREAD_CREATE_DETACHED);
    	//由于pthread_create的线程函数参数不能为内的非静态成员函数,所以定义了StartThread。
    	if (pthread_create(&m_thread,&m_attr, StartThread,this) == -1)
    	{
    		perror("Thread: create failed");
    		//设置线程未运行
    		SetRunning(false);
    	}
    #endif
    	//设置线程是否释放控制权
    	m_release = release;
    	//释放控制权
    	if (release)
    		m_sem.Post();
    }
    
    
    Thread::~Thread()
    {
    	m_b_destructor = true;
    	if (m_running)
    	{
    		SetRelease(true);
    		SetRunning(false);
    		/*
    			Sleep one second to give thread class Run method enough time to
    			release from run loop
    		*/
    		Utility::Sleep(1000);
    	}
    #ifdef _WIN32
    	if (m_thread)
    		::CloseHandle(m_thread);
    #else
    	pthread_attr_destroy(&m_attr);
    #endif
    }
    
    
    threadfunc_t STDPREFIX Thread::StartThread(threadparam_t zz)
    {
    	/*
    		Sleep here to wait for derived thread class constructor to setup
    		vtable... hurts just looking at it
    	*/
    	Utility::Sleep(5);
    
    	Thread *p = (Thread *)zz;
    
    	p -> Wait();
    	if (p -> m_running)
    	{
    		p -> Run();
    	}
    	//已经停止运行
    	p -> SetRunning(false); // if return
    	if (p -> DeleteOnExit() && !p -> IsDestructor())
    	{
    		delete p;
    	}
    #ifdef _WIN32
    	_endthreadex(0);
    #endif
    	return (threadfunc_t)NULL;
    }
    
    
    bool Thread::IsRunning()
    {
     	return m_running;
    }
    
    
    void Thread::SetRunning(bool x)
    {
     	m_running = x;
    }
    
    
    bool Thread::IsReleased()
    {
     	return m_release;
    }
    
    
    void Thread::SetRelease(bool x)
    {
     	m_release = x;
     	if (x)
     		m_sem.Post();
    }
    
    
    bool Thread::DeleteOnExit()
    {
    	return m_b_delete_on_exit;
    }
    
    
    void Thread::SetDeleteOnExit(bool x)
    {
    	m_b_delete_on_exit = x;
    }
    
    
    bool Thread::IsDestructor()
    {
    	return m_b_destructor;
    }
    
    
    void Thread::Wait()
    {
    	m_sem.Wait();
    }
    
    
    #ifdef SOCKETS_NAMESPACE
    }
    #endif
    
     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/1535.html

    关于

    发表评论

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享