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 ...
随机推荐
- ASP.NET MVC常见问题解决方法
1.页面报错: The following errors occurred while attempting to load the app. - No assembly found containi ...
- Catalan数总结
财产: 前20条目:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, ...
- linux(fedora) 下dvwa 建筑环境
linux(fedora)下dvwa组态 1.下载httpd,dvwa,mysql,mysqlserver, php-mysql,php 除了dvwa 这是外界进入下一官方网站.该服务通过休息inst ...
- P90
#include<stdio.h> #define N 4 int fun(int a[][N]) { int i,j,max=a[0][0]; for(i=0;i<2;i++) f ...
- 华为OJ: 公共字符串计算
有几个需要注意的地方,这个问题是不是大写和小写之间的区别.这样你就输入字符串大写或小写转换的计算前. 第二个,定要清晰.先将s1从[i]处開始与s2的[j]開始匹配,不相等则j++直到j等于s2.le ...
- HDU1253 胜利大逃亡 BFS
胜利大逃亡 Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submiss ...
- 霍夫曼(最优二叉树)和Java达到
一.定义 一些定义: 节点之间的路径长度:在从节点树中的一个节点也经历分公司,这构成的两个节点之间的路径分支的数目后这就是所谓的路径长度 的路径长度:从树的根节点到树中每一结点的路径长度之和. 在结点 ...
- 文《左右c++与java中国的垃圾问题的分析与解决》一bug分析
文<左右c++与java中国的垃圾问题的分析与解决>一bug分析 DionysosLai(906391500@qq.com) 2014/10/21 在前几篇一博客<关于c++与jav ...
- Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下
hibernate保存 hibernate要保存的目的是提供一个方法,多.它们之间有许多不同之处,点击此处详细说明.使得差: 一.预赛: 在所有.阐释.供hibernate,,transient.p ...
- NYoj 素数环(深搜入门)
题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=488 深搜模板: void dfs(int 当前状态) { if(当前状态为边界状 ...