浅谈.NET下的多线程和并行计算(一)前言

作为一个ASP.NET开发人员,在之前的开发经历中接触多线程编程的机会并不是很多,但是随着.NET 4.0的发布临近,我越来越感受到未来的1-2年中并行计算将会有很大的应用。于是决定通过写日志的方式来总结一下.NET 3.5下的多线程编程进而引入.NET 4.0提供的新的并行库以及新的并行编程模式和编程的思维方式。

个人觉得在日常的编程中对于ASP.NET程序员来说使用多线程编程不是很多,其实我们无时无刻不在享受多线程的优势。首先,WEB服务器环境就是一个多线程环境,每一个请求都是独立的线程,如果没有多线程很难想象只能同步处理一个请求的WEB服务器有什么用,类似,我们的数据库也应该是一个多线程环境。对于Windows应用程序的程序员来说恐怕就很难不接触多线程了,最简单的就是我们会新开线程去做一些耗时的操作,这样就可以避免UI停止响应,在操作结束后再把操作结果应用在主线程的控件上。虽然说这样的应用是多线程,甚至很多程序员习惯什么操作都新开一个线程去做,但是我觉得这样的多线程应用的思维还停留在单核时代,在多核时代,我们确实可以让任务实际的并行执行而不是看上去并行执行。Web前端框架最佳选择!

首先来说说概念,进程和线程的基本的概念不用多说,自然我们也能理解一个进程至少包含一个线程。通过在一个进程中开启多个线程,我们就可以让一个程序在同一时间看上去能做多个事情,比如可以在接受用户响应的时候进行一些计算。在以前处理器往往只有一个核心,也就是说在同一时间,处理器只能做一件事情。那么怎么实现之前说的多个线程同时执行呢。其实这个同时只是表面上看上去同时,本质上多个线程依次占用处理器的若干时间片,大家轮流使用其资源,由于这个时间片非常短,所以在一个长的时间看来似乎是几个线程同时得到了执行。

举一个生动的例子,我们经常看到有一些画家能同时在一个画布上画两个不同的图片,一个画人一个画房子,最后一起完成这个画。但仔细看的话发现,他是两手拿了两只画笔,在这里画一笔那里画一笔,在同一时间其实也只有一只笔在画。这个画家应该也像普通人一样是单核的,只是线程切换比较快罢了。我经常在打电话的时候和网友进行聊天,在同一时间做两件事情,但是这样很费脑子,在打字前我要回忆一下刚才聊天的内容,然后输入聊天的文字,然后再去回想一下刚才那哥们说了啥,在电话里面回他一句,这种回忆的工作就是准备线程的上下文,交给脑子去处理。虽然同一时间是做了两件事情,但是这个上下文的准备工作也浪费了点时间,如果我在打电话网络聊天的同事在去做第三件事情比如看电影,那我估计就不行了。所以,线程也不能开的很多,特别对于人脑来说。但是对于电脑处理器来说就不一样了,你只要准备好数据和指令他执行就是了,至于这些事情来自几件事情它不关心,24小时一秒都不浪费在执行指令完全没问题,当然你也可以让它闲着。Web前端框架最佳选择!

您可能会想了,既然线程切换需要时间,那么我们开两个线程执行两个任务不是还没有一个一个执行来的快吗?其实即使对于单核的处理器都不一定,因为在实际的应用中我们的任务往往不可能从头计算到尾一直占用处理器资源,在很多时候我们要等待IO响应或用户的响应,如果只是一个线程做事情的话处理器太闲了。对于现在多核的处理器来说,在同一时刻理论上可以在每一个处理器上都并行执行指令,我们就更需要利用多线程来提高运算速度了。当然也不是说一个任务要执行10秒,我们在双核的机器上并行执行这个任务只需要5秒了,那是因为很多时候这个任务很难划分成两个分支来并行执行,如果每个指令都要依靠上个指令的执行结果,那么这样的操作很难在多个处理器上并行执行。但是,我们可以这样想,至少如果有两个这样任务的话,我们就可以完全利用多个处理器的优势来并行执行了。

但是也不是多可以随便的开线程,每一个线程默认情况下都会占用1M的栈空间(对于普通应用程序来说),在32位Windows平台下可以给一个用户进程使用的程序最大在2G,那么也就是说在程序中使用的线程不能超过2000个,在实际测试中可以发现一般来说开1930左右个线程就会收到内存不足的异常,其实这个数量是绝对够用的,即使复杂的Outlook2007程序一般也只用了50个不到的线程(可以在任务管理器中观察到)。

在不得已的情况下很多人都不太会去使用多线程也是有原因的,一是因为多线程编程复杂,我们也习惯了一行一行代码执行的编程模式,对于一个好的多线程程序来说,要尽量分割任务让它在多个线程中使用以利用到多个处理器核。还有就是多个线程使用相同资源的话还要考虑资源的锁定以免产生数据的不一致。锁定/事务/并发的概念在数据库中也是非常常见的。二是因为调试困难,特别是一个线程的执行依赖其它线程的执行。三是因为多线程的程序随着环境的变化(处理器/操作系统)可能执行的性能还不一定相同,如果只针对某个环境进行编程可能还不能充分利用多处理器的优势。比如我们对一个任务划分成2个线程并行执行,那么对于四核的处理器来说,划分成4个线程并行执行会不会更合理呢,说实话我也举的这事挺难说的?还有,我们的编程基于.NET框架,而其本质还是使用的是操作系统的线程,操作系统中本来就有很多进程运行着,处理器是大家的处理器,不是专供我们程序使用的,在这么一个鱼龙混杂的环境,我们的程序究竟是不是会表现的如我们预期那样,也很难说。Web前端框架最佳选择!

多线程好,多线程难,本系列文章也只能在一个比较浅显的层次来谈谈如何在.NET框架中进行多线程编程,以及一些常见应用(比如Windows应用)中多线程的典型应用。希望对大家有帮助。

时间: 2024-08-17 05:59:02

浅谈.NET下的多线程和并行计算(一)前言的相关文章

浅谈.NET下的多线程和并行计算(二)线程基本知识

首先来看看如何创建线程: <span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8; color: rgb(43, 145, 175); ">Console</spa

浅谈Linux下Makefile编写

浅谈Linux下Makefile的编写 前言:本文简要介绍Makefile文件的编写规范,结合具体项目中的应用进行讲解. 具体代码地址: https://github.com/AnSwErYWJ/DogFood/blob/master/Makefile 简介 Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作.而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关

浅谈 js 下 with 对性能的影响

这几天多次看到有博主们在写 with 的文章,这货确实非常方便,但是却是个性能杀手,所以一直都是上不得台面的.那么他究竟会让效率低下到什么程度呢?先来看下 with 是如何的便捷吧.. // 正常调用 console.log(location.host); console.log(location.pathname); // 在 with 下 with (location) { console.log(host); console.log(pathname); } 如果不影响性能,确实是非常霸气

浅谈 IE下innerHTML导致的问题

原文:浅谈 IE下innerHTML导致的问题 先来看个demo吧: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>蚂蚁部落</title> <script type=&

[]转帖] 浅谈Linux下的五种I/O模型

浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html  一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer.如下图所示: 整个请求过程为: 用户进程发起请求,内核接受到请求后,从I/O设备中获取数据到buffer中,再将buffer中的数据copy到用户进程的地址空间,该用户进程获取到数

浅谈多核CPU、多线程、多进程

1.CPU发展趋势 核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核32线程),我们如何来面对这突如其来的核心数目的增加?编程也要与时俱进.笔者斗胆预测,CPU各个核心之间的片内总线将会采用4路组相连:),因为全相连太过复杂,单总线又不够给力.而且应该是非对称多核处理器,可能其中会混杂几个DSP处理器或流处理器. 2.多线程与并行计算的区别 (1)多线程的作用不只是用作并行计算,他还有很多很有益的作

&lt;转&gt;浅谈 Boost.Asio 的多线程模型

本文转自:http://senlinzhan.github.io/2017/09/17/boost-asio/ Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多线程的方式:全局只分配一个io_service,并且让这个io_service在多个线程之间共享,每个线程都调用全局的io_service的run()方法. 每个线程一个 I/O Serv

浅谈terminal下快速开启sublime text3

如何在命令行中快速开启sublime text3打开当前文件夹呢? mac下配置如下:1.open .zshrc 2. alias subl="'/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl'" alias nano="subl"                             export EDITOR="subl" 附:rvm与zsh问题: This so

[原创]浅谈Linux下的rpm

虽然现在很多人都使用yum去替代rpm了,但是rpm在一些特殊场合下还是有其作用的,比如查询跟验证已安装的rpm包,rpm全称Redhat Package Manager,是一种用于互联网下载包的打包及安装工具,它包含在某些Linux分发版中,它生成具有.RPM扩展名的文件,与Dpkg类似. rpm的常用功能分两大块: (1)查询/核实软件包是否被安装:rpm {-q|--query} [select-options] [query-options]         (用的多) rpm {-V|