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 ...
随机推荐
- 达到HTTP合约Get、Post和文件上传功能——采用WinHttp介面
于<采用WinHttp实现HTTP协议Get.Post和文件上传功能>一文中,我已经比較具体地解说了怎样使用WinHttp接口实现各种协议. 在近期的代码梳理中,我认为Post和文件上传模 ...
- Java绘制艺术图形
本例主要是通过使用坐标轴平移,图形旋转和获得随机数等技术来绘制艺术图案.通过重写JPanel类中的paint()方法,并在该方法中使用Graphics2D类中的translate(),setColor ...
- 恢复SQLServer实例连接
原文:恢复SQLServer实例连接 译自: http://www.mssqltips.com/sqlservertip/2682/recover-access-to-a-sql-server-ins ...
- 鸟哥Linux私房菜 基础学习篇读书笔记(10):Linux磁盘和文件系统管理(3)
本文总结了Linux操作系统来管理我们的硬盘和文件系统需要使用命令.当我们在系统中增加一个硬盘驱动器.什么是我们需要去通过这个硬盘就可以真正使用步骤?下面步骤: (1)对磁盘进行分区,新建能够使用的分 ...
- "伪中国移动client"--伪基站诈骗
一.简单介绍: 近日,百度安全实验室发现一款"伪中国移动client"病毒.犯罪分子通过伪基站方式大量发送伪10086的短信,诱导用户点击钓鱼链接:并在钓鱼页面诱导用户输入网银账号 ...
- ZOJ 3822 可能性DP
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3822 本场比赛之前,我记得.见WALK概率路DP称号.那么它应该是可以考虑 ...
- Python installation
PIP:Python & OS Support pip works with CPython versions 2.6, 2.7, 3.2, 3.3, 3.4 and also pypy. p ...
- DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表
原文:DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用 ...
- ArcEngine下一个TIN生成的轮廓
太晚了,直接连接的源代码: /// <summary> /// TIN生成等高线 /// </summary> /// <param name="pInterv ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(3)-面向接口的编程
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(3)-面向接口的编程 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1)框架搭建 (2):数据 ...