随着计算机CPU计算能力快速提高,计算机的处理性能和并行性能力也大大提升。那么,一味使用运行时标准库的C++语言也应该开始支持多线程技术。今天,我为大家带来了C++在windows平台下的常用多线程方法。

首先我先说一下线程的状态。线程有挂起状态、执行状态、阻塞状态和等待状态,下面分别介绍:挂起状态是说线程创建后并没有直接执行或是调用函数挂起了线程。被挂起了的线程没有执行的能力,只有调用启动函数了之后才能执行。而执行状态是指在线程的时间片内,拥有CPU资源的时候,这是,线程便开始执行。阻塞状态是由于进行大量输入输出操作或发生执行错误时,线程失去执行状态,只有等待问题解除之后,线程才能进入等待状态。等待状态是指线程启动或时间片抢占失败是等待其他线程执行,在此期间,线程随时可能被执行。那么,请大家看一个流程图:

因为C++不像Java一样需要进行跨平台优化,所以我们使用最简单的方法来实现多线程技术——windows.h中的CreateThread以及相关函数和类。首先,以如下的方式引用头文件:

#include <windows.h>

下面,我们来介绍如何创建线程,我不会向一般的教程那样上来先罗列一大堆MSDN上的函数原型,把大家弄得糊里糊涂了再讲,我首先先把函数原型翻译成中文好了:

线程句柄 CreateThread(
线程安全性描述(一个结构体,一般是NULL)LPSECURITY_ATTRIBUTES lpThreadAttributes,
一种数值(栈深度,一般是0)DWORD dwStackSize,
启动函数(一般情况如下阐述) LPTHREAD_START_ROUTINE lpStartAddress,
附加参数(一般为NULL) LPVOID lpParameter,
运行参数(是否在创建完成后就启动线程,具体下面将)DWORD dwCreationFlags,
返回句柄(一般是0,或者是一个DWORD型变量的地址,别忘了&)LPDWORD lpThreadId);

下面我就重点说一下:

//这第三个参数启动函数很重要:
LPTHREAD_START_ROUTINE lpStartAddress
//我们一般这样写:
(LPTHREAD_START_ROUTINE) ThreadStart
//意思就是在线程启动的时候调用ThreadStart,之后他就不管了,也就是说这个函数就是线程主函数相当于main的意思。也就是说在这个函数中调用的类资源或函数资源都是属于这个线程的。除了static的存储类

还有我要说一下HANDLE这个类型,它其实是一个指针,也是CreateThread的返回值。也就是一个线程句柄,用于标示一个线程。当然,其他对于线程的操作都需要使用这个指针。如果你没有学过指针引用,还是好好复习一下*和&吧。对了还有->。我为什么要介绍HANDLE呢?因为我将要说一下倒数第二个参数——运行参数。这是实际上是一个bool类型的值,用于标示是否在创建线程后立刻执行,如果为true,也就是0,那么就会立刻执行,否则将会挂起,等待启动。那么,我们用以下方法启动线程:

DWORD ResumeThread(HANDLE hThread); //启动线程
//说明:DWORD是一个数值,代表句柄,无需关注;
//参数表示要启动的线程的句柄,也就是刚才介绍的由CreateThread返回的HANDLE

如果调用这个函数,将会启动HANDLE参数所代表的线程。下面我们看看如何挂起线程,使线程进入挂起状态:

DWORD SuspendThread(HANDLE hThread); //挂起线程
//说明:DWORD是一个整数值,代表一个句柄,无需过分关注
//参数:一个HANDLE线程指针,由CreateThread创建
//功能:挂起线程直到使用ResumeThread

挂起线程后可以进行释放以便停止线程:

delete HANDLE //释放指针资源
//说明:HANDLE是一个HANDLE型指针,代表释放一个线程的资源,使线程死亡

挂起线程也可能为了等待重要操作然后再执行线程,以下函数将解除线程挂起状态,使线程进入等待状态:

DWORD ResumeThread(HANDLE hThread); //使线程脱离挂起状态
//说明:返回值也是句柄
//参数:HANDLE类型指针,表示要继续的线程,或刚创建而没有启动的线程
//注意:如果对等待状态下的线程使用本函数,可能会抛出异常或无效果,具体请见MSDN

实际上,停止一个线程还有一种方法——强行停止,但是已经不建议使用,现在都是使用挂起+delete的方法,因为使用强行停止会有很多的安全问题,但也是一个功能,所以在这里为大家介绍一下:

BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode); //强行停止线程
//说明:返回值代表是否成功
//参数:HANDLE指针代表需要结束的线程,DWORD数值代表该线程的退出值
//功能:在任何位置结束任何线程

那么,关于多线程的基本C++API就讲完了,那么我要说一个关键字——volatile。它代表“易变的”,编译器不会优化使用这个关键字生命的全局变量,保证此变量完全“听你的话”。那么,就可以实现简单的线程间通讯。接着,来写一个比较简单的例程,本来是Java1234的多线程例程,现在被我改成了C++版本。请看:

//多线程抢占输出
#include <iostream>
#include <windows.h> using namespace std; void ThreadUser(){ //线程入口
cout<<"子线程开始"<<"\n";
for(int i=0;i<100;++i){ //抢占循环
cout<<"子线程第"<<i<<"次循环抢占;"<<"\n"; //输出信息
Sleep(100); //抢占延时
}
cout<<"子线程结束"<<"\n";
} int main(){
cout<<"主线程开始"<<"\n";
HANDLE h; //线程句柄
CreateThread(null,0,(LPTHREAD_START_ROUTINE)ThreadUser,null,1,0); //创建子线程
ResumeThread(HANDLE); //启动子线程
for(int i=0;i<100;++i){ //抢占循环
cout<<"主线程第"<<i<<"次循环抢占;"<<"\n"; //输出信息
Sleep(100); //抢占延时
}
Sleep(1000); //等待子线程
delete h; //回收子线程资源
cout<<"主线程结束"<<"\n";
system("pause");
return 0;
}

好了,我们的多线程就先讲到这里,下次再见。

顺便说一下,我们的老朋友windows XP今天退役了,大家默哀一下吧……

欢迎继续关注BKMMSC-金鸡独立的博客。再见!

C++多线程技术windows常用方法的更多相关文章

  1. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  2. 基于JAVA语言的多线程技术

    1.简介 多线程技术属于操作系统范围内的知识: 进程与线程 可以这么理解,一个应用程序就是一个进程,在一个进程中包含至少一个线程:进程就是线程的容器,真正工作.处理任务的是线程. 进程是操作系统分配资 ...

  3. OS X 和iOS 中的多线程技术(上)

    OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供 ...

  4. Java中的多线程技术全面详解

    本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...

  5. 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!

    Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...

  6. C# 多线程技术

    这节讲一下多线程(Thread)技术. 在讲线程之前,先区分一下程序,进程,线程三者的区别,大体上说,一个程序可以分为多个进程,一个进程至少由一个线程去执行,它们是层层包含的关系.我们写的程序,就是一 ...

  7. iOS多线程技术方案

    iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...

  8. C#多线程技术总结(异步)

    我这里针对现有的C#多线程技术进行一个汇总,一是复习,二是方便索引,文章部份知识点来源于网络,非本人原创. 一.并行(异步): 1.System.Threading.Tasks命名空间下的(TPL): ...

  9. iOS开发之多线程技术

    本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...

随机推荐

  1. mmc生产运输问题

    本题目结合生产和运输,增加了约束, 其实,比较生产,运输问题,大同小异, 解法基本相同.

  2. Apache Solr采用Java开发、基于Lucene的全文搜索服务器

    http://docs.spring.io/spring-data/solr/ 首先介绍一下solr: Apache Solr (读音: SOLer) 是一个开源.高性能.采用Java开发.基于Luc ...

  3. [Bower] Bower

    //search bower search jquery bower search jquery | grep formstyler //info bower info jquery //instal ...

  4. 理解WebKit和Chromium: 调试Android系统上的Chromium

    转载请注明原文地址:http://blog.csdn.net/milado_nju 1. Android上的调试技术 在Android系统上,开发人员能够使用两种不同的语言来开发应用程序,一种是Jav ...

  5. 网络IPC:套接字之套接字选项

    套接字机制提供两个套接字选项接口来控制套接字的行为.一个接口用来设置选项,另一个接口允许查询一个选项的状态.可以获取或设置的三种选项: (1)通用选项,工作在所有套接字类型上. (2)在套接字层次管理 ...

  6. 将Eclipse中现有的java类生成类图

    需求:将Eclipse中现有的java类生成类图 一:什么是ModelGoon? 它是一个Eclipse插件,用于基于UML图的模型设计,以及逆向工程(即从已有源代码生成类图). 二:安装 下载Mod ...

  7. Android基本控件之ListView(二)<ListView优化>

    之前我们说到ListView的基本用法.但是,有很多的时候会额外的占用一些内存,从而消耗了性能.既然有消耗性能的可能,那么我们就对其做出相应的优化 我们首先来说说优化的步骤: 第一步.将宽和高设置为填 ...

  8. objc_msgSend消息传递学习笔记 – 消息转发

    该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文. 消息转发机制(message forwarding) Objective-C 在调用对 ...

  9. Asp.Net 之 通过调用 WScript.Shell 启动本地 exe 程序时产生“ automation服务器不能创建对象 ”的错误

    我们经常需要通过生成 ActiveXObject("WScript.Shell"); 来调用某一exe文件. 设置网页打印的页眉页脚为空: var HKEY_Root,HKEY_P ...

  10. struts2.1笔记07:Sturts.xml配置中的包介绍

    1. 2.这里上面namespace作用是介绍: (1)如果<package>配置在struts1中如下: (2)同样的配置在struts2中如下: