.Net多线程编程—预备知识
1 基本概念
共享内存的多核架构:一个单独的封装包内封装了多个互相连接的未处理器,且所有内核都可以访问主内存。共享内存的多核系统的一些微架构,例如内核暂停功能,超频。
内核暂停功能:当使用内核不多的时候,操作系统会使剩下的内核进入休眠状态,当需要使用这些内核时,操作系统会唤醒这些睡眠的内核。
超频:提升一个内核频率的过程。当内核工作繁重时,使内核以更高的频率工作。
分布式内存系统:由多个处理器(CPU)组成,每个处理器可以位于不同的计算机上,计算机之间可以有不同类型的通信信道,并且都有自己私有的内存。
物理内核:物理内核是真正独立的处理单元。
硬件线程(逻辑内核\逻辑处理器):每个物理内核可能会提供多个逻辑内核。
软件线程(一般称作线程):程序执行流的最小单元,有时被称为轻量级进程(Lightweight Process,LWP)。每一个软件线程与其父进程分享一个私有的唯一的内存空间,但每一个软件线程有自己的栈、寄存器和私有局部存储区域。
进程:是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。Windows中每个运行的程序都是一个进程。
主线程:当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程。一个进程至少有一个主线程。
超额申请:应用程序使用的并发线程数多于逻辑内核数时发生超额申请。
负载均衡:不同的任务分配到的工作量差不多,以便有效利用处理器资源。
负载失衡:不同的任务分配到的工作量不同,以致有些任务无事可做,没有有效地利用处理器资源。
并发:多条指令在同一时间段执行。
并行:当系统有一个以上CPU空闲可用时,两个线程互不抢占CPU资源,可以同时进行,这种方式称之为并行。
交错并发:一次执行一个线程的指令,两个线程的指令交错执行。
竞争:计算结果依赖于语句执行的顺序,而执行的顺序没有被控制或同步。
竞争条件:竞争出现的条件。
死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
活锁:与死锁相似,不同之处在于活锁中的线程状态不断地在两个状态之间切换且线程没有被阻塞。
锁争用:多个线程竞争同一个锁。
锁封护:当多个优先级相同的线程反复争用同一个锁时会发生锁封护。与死锁和活锁的情况不同,处于锁封护中的线程仍会前进;但是线程每次企图获取锁并且失败时,它会让出剩余的调度量并强制上下文切换。
临界区:两个并行部分之间需要顺序执行的串行时间段称为临界区。
.NET Framework 4引入的TPL:.NET Framework 4引入了新的TPL(任务并行库,Task Parallel Library),使用新型轻量级并发模型。新的TPL支持数据并行,任务并行和流水线。
1)数据并行:针对大量需要处理的数据,每一份数据执行同样的操作。
2)任务并行:并发运行不同的操作。
3)流水线:数据并行与任务并行的结合体,要对多个并发的任务进行协调。
2 概念辨析
1)并发、交错并发
图1 为并发示意图,其中有两个线程,编号分别为0和1。每个线程有两个指令,0-0表示第一个线程的第一条指令,0-1表示第一个线程的第二条指令,其他依次类推。
图2 为交错并发的示意图,其中有两个线程,编号分别为0和1。每个线程有两个指令,0-0表示第一个线程的第一条指令,0-1表示第一个线程的第二条指令,其他依次类推。从图中可看出,两个线程的指令交替执行,一次只执行一条指令。

图1 并发
图2 交错并发
2)物理内核、硬件线程
Intel Core i5-3470 Processor 有四个物理内核,每个内核有一个硬件线程。
Intel Xeon Processor E7-8893 v4 有四个物理内核,每个内核有两个硬件线程。
可见一个Processor的物理内核个数不一定等于硬件线程数。

图3 Intel Core i5-3470 Processor

图4 Intel Xeon Processor E7-8893 v4
3 Amdahl法则与Gustafson法则
Amdahl法则
功能:预测多处理器系统的最大理论性能提升(加速比,speedup)
公式:最大加速比(倍数)= 1/((1-P)+(P/N))
其中:P表示能够完全并行运行的代码比例
N表示可用的计算机单元(处理器或物理内核数)
法则缺陷:
只考虑了物理内核数的变化,并未考虑可以在既有应用程序中添加新功能以充分利用增加的并行处理能力。
只考虑了硬件的变化,并未考虑待处理的问题规模的变化。
未考虑并行所带来的开销。
未考虑将串行部分转换为充分利用并行化的算法。
Gustafson法则
功能:通过问题的大小来预测在固定时间内可执行的工作量
公式:工作总量(单元数)=S+N*P
其中:S表示一次顺序执行完成的工作单元数
P表示每一部分能够完全并行执行的工作单元数
N表示可用的执行单元数(处理器数或物理内核数)
法则缺陷:
未考虑并行所带来的开销。
未考虑将串行部分转换为充分利用并行化的算法。
推出编程指导原则:
当程序串行部分消耗时间和问题大小有关时,调整问题大小以获得更好的加速比。
当可并行处理的数据量有限时,可添加新功能,以充分利用现代硬件的并行处理能力。
尽量减少临界区。
4.多核并行程序设计原则
(1)按照并行的方式思考
(2)使用抽象功能,充分利用.NET Framework 4中的TPL(Task Parallel Library)所提供的新功能
(3)按照任务(事情)编程,而不是按照线程(CPU内核)编程,关注任务而非底层线程
(4)设计的时候考虑关闭并发的情形,考虑程序在单核处理器也可运行
(5)避免使用锁
(6)利用为了帮助并发而设计的工具和库
(7)使用可扩展的内存分配器
(8)设计的时候要考虑随增长的工作负载而扩展
参考材料:
1)C#并行编程高级教程(中文版)(美)希拉里著,郑思遥/房佩慈译,清华大学出版社出版
2)设计模式.NET并行编程(中文版)
3)https://en.wikipedia.org/wiki/Lock_convoy
4)https://en.wikipedia.org/wiki/Deadlock#Livelock
5)https://en.wikipedia.org/wiki/Concurrent_computing
6)https://en.wikipedia.org/wiki/Parallel_computing
7)http://ark.intel.com/products/68316/Intel-Core-i5-3470-Processor-6M-Cache-up-to-3_60-GHz
8)http://ark.intel.com/products/93791/Intel-Xeon-Processor-E7-8893-v4-60M-Cache-3_20-GHz
-----------------------------------------------------------------------------------------
转载与引用请注明出处。
时间仓促,水平有限,如有不当之处,欢迎指正。
.Net多线程编程—预备知识的更多相关文章
- iOS多线程编程的知识梳理
多线程编程也称之为并发编程,由于其作用大,有比较多的理论知识,因此在面试中也是受到面试官的青睐.在日常项目开发中,至少网络请求上是需要使用到多线程知识的,虽然使用第三方的框架比如AFNetworkin ...
- 【转】Linux下的多线程编程背景知识
1. 进程和线程 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(pr ...
- Java多线程编程基础知识汇总
多线程简介 多任务 现代操作系统(Windows.Linux.MacOS)都可以执行多任务,多任务就是同时运行多个任务.例如在我们的计算机上,一般都同时跑着多个程序,例如浏览器,视频播放器,音乐播 ...
- C++ 系列:多线程编程基础知识
Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
- C++多线程编程入门之经典实例
多线程在编程中有相当重要的地位,我们在实际开发时或者找工作面试时总能遇到多线程的问题,对多线程的理解程度从一个侧面反映了程序员的编程水平. 其实C++语言本身并没有提供多线程机制,但Windows系统 ...
- android: 多线程编程基础
9.1 服务是什么 服务(Service)是 Android 中实现程序后台运行的解决方案,它非常适合用于去执行那 些不需要和用户交互而且还要求长期运行的任务.服务的运行不依赖于任何用户界面,即使 ...
- .NET多线程编程(转)
在.NET多线程编程这个系列我们讲一起来探讨多线程编程的各个方面.首先我将在本篇文章的开始向大家介绍多线程的有关概念以及多线程编程的基础知识;在接下来的文章中,我将逐一讲述.NET平台上多线程编程的知 ...
- Java基础知识➣多线程编程(五)
概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源, ...
- Java 多线程编程知识详解
Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特别的形式,但多线程使用 ...
随机推荐
- 干货分享:让你分分钟学会 JS 闭包
闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
- C#中5步完成word文档打印的方法
在日常工作中,我们可能常常需要打印各种文件资料,比如word文档.对于编程员,应用程序中文档的打印是一项非常重要的功能,也一直是一个非常复杂的工作.特别是提到Web打印,这的确会很棘手.一般如果要想选 ...
- 代码的坏味道(22)——不完美的库类(Incomplete Library Class)
坏味道--不完美的库类(Incomplete Library Class) 特征 当一个类库已经不能满足实际需要时,你就不得不改变这个库(如果这个库是只读的,那就没辙了). 问题原因 许多编程技术都建 ...
- C# 工厂模式+虚方法(接口、抽象方法)实现多态
面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...
- 用C++实现Linux中shell的ls功能
实现输出当前目录下的文件名 ls功能: 方法一: #include <iostream> #include <algorithm> #include <stdio.h&g ...
- 执行git push出现"Everything up-to-date"
在github上git clone一个项目,在里面创建一个目录,然后git push的时候,出现报错"Everything up-to-date" 原因:1)没有git add . ...
- 判断一个对象是jQuery对象还是DOM对象
今天调试一段代码的时候,看到其中一个变量,想知道它到底是jquery对象还是dom对象. 虽然直接console出这个对象,看它的内部可以判断出来.但是我想有没有什么更方便的方法呢. 后来我想到了一个 ...
- 分享阿里云推荐码 IC1L2A,购买服务器可以直接打9折,另附阿里云服务器部署ASP.NET MVC5关键教程
阿里云推荐码为:IC1L2A 阿里云还是不错滴. 以windows server 2008 R2为例,介绍如何从全新的服务器部署MVC5 站点. 新购买的阿里云服务器是没有IIS的,要安装IIS: 控 ...