zoukankan      html  css  js  c++  java
  • C++多线程分析

            我们开始谈论的线程之前先看看这些线载波前—进程。

    进程,它是一个正在执行的程序的实例。是一个程序在其自身的地址空间的一次执行活动。进程是资源申请、调度、和独立执行的基本单位。进程有两部分组成:

            1、操作系统用来管理进程的内核对象。内核对象是系统用来存放关于进程的统计信息的地方,它是操作系统内部分配的一块内存块,该内存块是一种数据结构,其成员负责维护该对象的各种信息。

            2、地址空间,它包括全部可运行模块、dll模块的代码和数据,也包括动态内存分配的空间。

            线程---操作系统调度的最小单位。线程包括在进程中,是进程中实际执行的单位。一个进程中能够同一时候执行多个线程。每一个线程能够执行不同的任务。这就是所谓的多线程。

    同一进程中的多个线程将共享该进程中的所有系统资源,如虚拟地址空间、文件描写叙述符和信号处理等,可是同一个进程中的多个线程都有各自的调用栈、寄存器环境和线程本地存储。

            对于单核(单CPU)系统来说,即便处理器一次仅仅能执行一个线程,可是操作系统通过时间片轮转技术。在不同的线程之间进行切换,让用户产生能够同一时候处理多个任务的错觉,这种程序执行机制称为软件的多线程。

             对于多核(多个CPU)系统来说,这种系统能同一时候进行真正的多线程多任务处理。这种执行机制能够称为硬件的多线程技术。

            多线程程序作为一种多任务、并发的工作方式。当然有下面的长处:

            1)、提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时非常长时,整个系统都会等待这个操作。此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术。将耗时长的操作(time consuming)置于一个新的线程。能够避免这样的尴尬的情况。

           2)、使多CPU系统更加有效。

    操作系统会保证当线程数不大于CPU数目时,不同的线程执行于不同的CPU上。

           3)、改善程序结构。一个既长又复杂的进程能够考虑分为多个线程,成为几个独立或半独立的执行部分。这种程序会利于理解和改动。

    例如以下是我写一个跨平台的线程样例:

    Mutex.h
    
    #ifndef HEART_MKITHEART_MMUTEX_H
    #define HEART_MKITHEART_MMUTEX_H
    
    #ifdef WIN32
    #	include <windows.h>
    #else
    #	include <pthread.h>
    #endif
    
    #ifdef WIN32
    typedef CRITICAL_SECTION        MKIT_MUTEX_SECTION;
    #	define MKIT_MUTEX_INIT         ::InitializeCriticalSection
    #	define MKIT_MUTEX_DESTROY      ::DeleteCriticalSection
    #	define MKIT_MUTEX_LOCK         ::EnterCriticalSection
    #	define MKIT_MUTEX_UNLOCK       ::LeaveCriticalSection
    #else
    typedef pthread_mutex_t         MKIT_MUTEX_SECTION;
    #	define MKIT_MUTEX_INIT         pthread_mutex_init
    #	define MKIT_MUTEX_DESTROY      pthread_mutex_destroy
    #	define MKIT_MUTEX_LOCK         pthread_mutex_lock
    #	define MKIT_MUTEX_UNLOCK       pthread_mutex_unlock
    #endif
    
    class Mutex
    {
    public:
    	Mutex()
    	{
    		MKIT_MUTEX_INIT(&m_mutex
    #ifndef _WIN32
    			, NULL
    #endif
    			);
    	}
    
    	virtual ~Mutex() {MKIT_MUTEX_DESTROY(&m_mutex);}
    	virtual void Lock() const {MKIT_MUTEX_LOCK(&m_mutex);}
    	virtual void Unlock() const { MKIT_MUTEX_UNLOCK(&m_mutex); }
    
    private:
    	mutable MKIT_MUTEX_SECTION m_mutex;
    };
    
    class AutoLock
    {
    public:
    	AutoLock(const Mutex& mutex, bool autolocked = true) : m_mutex(&mutex), m_locked(true)
    	{
    		if(autolocked)
    		{
    			m_mutex->Lock();
    			m_locked = autolocked;
    		}
    	};
    
    	~AutoLock()
    	{
    		if(m_locked)
    		{
    			m_mutex->Unlock();
    		}
    	};
    
    private:
    	const Mutex* m_mutex;
    	bool m_locked;
    };
    
    #ifndef LOCK
    #	define LOCK(mutex) AutoLock locker(mutex)
    #endif
    
    #endif//HEART_MKITHEART_MMUTEX_H

    Thread.h
    
    #ifndef HEART_MKITHEART_MTHREAD_H
    #define HEART_MKITHEART_MTHREAD_H
    
    #include "Mutex.h"
    
    #define RET_SUCCEED 0
    
    
    class Runnable
    {
    public:
    	virtual void Run() = 0;
    };
    
    class Thread : public virtual Runnable
    {
    	Thread(const Thread&);
    	const Thread& operator=(const Thread&);
    
    public:
    	Thread();
    	~Thread();
    
    #ifdef WIN32
    	static unsigned int WINAPI ThreadFun(void* t);
    #else
    	static void* ThreadFun(void* t);
    #endif
    
    	int Start(void);
    	int Stop(void);
    
    	inline bool IsRunning(void) { return m_running; }
    	inline void SetRunning(bool x) { m_running = x; }
    	inline unsigned short GetWaitTime(void) { return m_waitTime; }
    	inline void SetWaitTime(unsigned short uTime) { m_waitTime = uTime;}
    	inline void SetRunnable(Runnable* pRunnable){ m_runnable = pRunnable; }
    
    public :
    	virtual void Run();
    
    protected:
    	void WatiTime(int mTime);
    
    private:
    #ifdef WIN32
    	HANDLE          m_handle;
    	unsigned int    m_threadID;
    #else
    	pthread_t       m_thread_t;
    	pthread_attr_t  m_attr;
    #endif
    
    private:
    	unsigned short	m_waitTime;
    	bool			m_running;
    	Runnable*		m_runnable;
    	Mutex          m_mutex;
    };
    
    
    #endif//HEART_MKITHEART_MTHREAD_H

    Thread.cpp
    
    #ifdef WIN32
    #	include <process.h>
    #else
    #	include <sys/time.h>
    #	include <sys/types.h>
    #endif
    
    #include "Thread.h"
    
    
    
    Thread::Thread() : m_handle(0), m_runnable(0), m_running(false), m_waitTime(40)
    {
    }
    
    Thread::~Thread()
    {
    	Stop();
    }
    
    void Thread::Run()
    {
    	if(m_runnable)
    	{
    		m_mutex.Lock();
    		m_runnable->Run();
    		m_mutex.Unlock();
    	}
    	WatiTime(m_waitTime);
    }
    
    #ifdef WIN32
    unsigned int Thread::ThreadFun( void* t )
    #else
    void * Thread::ThreadFun( void* t )
    #endif 
    {
    	Thread *p = (Thread*)(t);
    	if(t)
    	{
    		while (p->IsRunning())
    		{
    			p->Run();
    		}
    #ifdef WIN32
    		_endthreadex(0);
    #else
    		pthread_exit((void*)0);
    #endif
    	}
    	return RET_SUCCEED;
    }
    
    int Thread::Start( void )
    {
    	if(!IsRunning())
    	{
    #ifdef WIN32
    		m_handle = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, this, 0, &m_threadID);//CREATE_SUSPENDED
    #else
    		pthread_attr_init(&m_attr);
    		pthread_attr_setdetachstate(&m_attr, PTHREAD_CREATE_DETACHED);
    
    		if (-1 == pthread_create(&m_thread_t, &m_attr, ThreadFun, this))
    		{
    			SetRunning(false);
    			return -1;
    		}
    #endif
    		SetRunning(true);
    	}
    	return RET_SUCCEED;
    }
    
    int Thread::Stop( void )
    {
    	if (IsRunning())
    	{
    		m_mutex.Lock();
    		SetRunning(false);
    		m_mutex.Unlock();
    	}
    
    #ifdef Win32
    	if(m_handle)
    	{
    		::WaitForSingleObject(m_handle, 50);
    		::CloseHandle(m_handle);
    		m_handle = NULL;
    	}
    #endif
    	return RET_SUCCEED;
    }
    
    #ifdef WIN32
    void Thread::WatiTime(int mTime)
    {
    	Sleep(mTime);
    }
    
    #else
    
    pthread_cond_t  g_timer_cond;
    pthread_mutex_t g_timer_mutex;
    
    void Thread::WatiTime(int mTime)
    {
    	struct timeval temp_timeout;
    	gettimeofday(&temp_timeout, 0);
    
    	struct timespec timeOut;
    
    	timeOut.tv_sec = temp_timeout.tv_sec;
    	timeOut.tv_nsec = (temp_timeout.tv_usec  + mTime * 1000) * 1000;
    
    	pthread_cond_timedwait(&g_timer_cond, &g_timer_mutex, &timeOut);
    }
    #endif


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    JavaWeb 之 表单重复提交问题
    JavaWeb 之 验证码
    JavaScript 之 AJAX 请求
    JavaWeb 之 i18N 国际化
    JavaWeb 之 Gson 的使用
    JavaScript 之 JSON 对象
    JavaWeb 之 由 Tomcat 展示友好的错误信息页面
    【LeetCode-动态规划】完全平方数
    【LeetCode-递归】至少有K个重复字符的最长子串
    【LeetCode-设计】常数时间插入、删除和获取随机元素
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4708976.html
Copyright © 2011-2022 走看看