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
版权声明:本文博客原创文章,博客,未经同意,不得转载。
C++多线程分析的更多相关文章
- Android多线程分析之五:使用AsyncTask异步下载图像
Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...
- Android多线程分析之四:MessageQueue的实现
Android多线程分析之四:MessageQueue的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前面两篇文章<Androi ...
- Android多线程分析之三:Handler,Looper的实现
Android多线程分析之三:Handler,Looper的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多 ...
- Android多线程分析之二:Thread的实现
Android多线程分析之二:Thread的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多线程分析之一 ...
- Android多线程分析之一:使用Thread异步下载图像
Android多线程分析之一:使用Thread异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 打算整理一下对 Android F ...
- Android四个多线程分析:MessageQueue实现
Android四个多线程分析:MessageQueue的实现 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在前面两篇文章<Android多线 ...
- Android多线程分析之中的一个:使用Thread异步下载图像
Android多线程分析之中的一个:使用Thread异步下载图像 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可.转载请注明出处 打算整理一下对 Android Fr ...
- C++双缓冲多线程分析大文件词频
实习生活告一段落,我正式从一名.NET程序员转入Java阵营,不得不说刚开始用Java的东西是多么的不习惯,但是经过三个月的使用与开发,我也发现了Java的优势:不在于语言,而在于开源.这意味着有更多 ...
- 单例模式中的多线程分析synchronized
谈到单例模式,我们立马会想到饿汉式和懒汉式加载,所谓饿汉式就是在创建类时就创建好了实例,懒汉式在获取实例时才去创建实例,即延迟加载. 饿汉式: 1 package com.bijian.study; ...
- Java多线程分析案例
1. 多线程的创建方式 (1).继承 Thread类:但Thread本质上也是实现了Runnable 接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过 Thread 类的 sta ...
随机推荐
- Visual Studio 原生开发的10个调试技巧(二)
原文:Visual Studio 原生开发的10个调试技巧(二) 我以前关于 Visual Studio 调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你可以看到写原 ...
- boostrap-非常好用但是容易让人忽略的地方------clearfix
代码 显示结果 代码 结果
- eclipse 对齐行号在括号中显示和字体调整
笔者 : 本笃庆军 一.括号对齐:指和C/C++里面一样.上下括号对齐~~~ 第一步:Project->preferences->Java->Code Style->Forma ...
- C# 合并DLL, 合并DLL进入EXE
原文:C# 合并DLL, 合并DLL进入EXE 使用方法非常简单 在项目属性窗口中,选择"生成事件",在"生成后事件命令行"下的文本框中输入 ilmerge / ...
- C# .net基于Http实现web server(web服务)
原文:C# .net基于Http实现web server(web服务) 什么是 web server? 百度百科是这么解释的: Web Server中文名称叫网页服务器或web服务器.WEB服务器也 ...
- ENode简介与各种资源汇总
ENode简介与各种资源汇总 ENode是什么 ENode是一个.NET平台开源的应用开发框架,为开发人员提供了一套完整的基于DDD+CQRS+ES+(in-memory)+EDA架构风格的解决方案. ...
- Linux下的变化的主机名步骤
Linux下变化的主机名gpdb 步骤1.执行vi /etc/sysconfig/network命令 NETWORKING=yesHOSTNAME=gpdb 第二步.执行hostname gpdb令 ...
- Matlab曲面拟合和插值
插值和拟合都是数据优化的一种方法,当实验数据不够多时常常须要用到这样的方法来绘图. 在matlab中都有特定的函数来完毕这些功能. 这两种方法的确别在于: 当測量值是准确的,没有误差时,一般用插值: ...
- IEnumerable,IQueryable的区别
IEnumerable,IQueryable之前世今生 IEnumerable<T>在.Net2.0中我们已经很熟悉了.你想要利用Foreach迭代吗?实现IEnumerable<T ...
- jQuery中的 return false, e.preventDefault(), e.stopPropagation()的区别
e.stopPropagation()阻止事件冒泡 <html><head> <title></title> <script sr ...