多线程(1)认识多线程

  多线程在项目开发过程中非常非常重要,这个系列就来详细总结一下,首先认识一下多线程。

windows为什么要支持多线程

计算机的早期时代,操作系统没有线程的概念,整个系统只运行着一个执行线程,其中包含操作系统代码和应用程序代码。只用一个执行线程的问题在于,长时间运行的任务会阻止其他任务的执行。例如16位Windows的时代,打印文档的应用程序很容易“冻结”整个机器。

Microsoft 在设计Windows NT这个版本的OS内核时,决定在一个进程中运行应用程序的每个实例。进程实际是应用程序的实例要使用的资源的集合。每个进程都被赋予了一个虚拟地址空间,确保一个进程中使用的代码和数据无法由另一个进程访问。这就确保了应用程序实例的健壮性。同时,进程访问不了OS的内核代码和数据;所以,应用程序代码破坏不了操作系统的代码和数据

如果应用程序发生死循环会发生什么?如果机器只有一个CPU,它会执行死循环,不能执行其他任何程序。Microsoft 的解决方案就是线程。作为一个Windows概念,线程的职责是对CPU进行虚拟化。Windows为每个进程都提供了该进程专用的线程(功能相当于一个CPU)。应用程序的代码进行死循环,与代码关联的进程会“冻结”,但其他进程(它们有自己的线程)不会冻结,它们会继续执行。
线程很强大,因为它们使Windows即使在执行长时间运行的任务时,也能随时响应。

所以多线程的发展历史可以简单总结为:没有线程(只有一个执行线程)--->引入进程--->引入多线程

线程的开销

线程是给我们带来好处的同时,也有性能的损失,包括空间上和时间上的。

1,空间上

创建一个线程需要加载以下资源:

  • 线程内核对象(thread kernel object),操作系统为系统中创建的每个线程都会分配并初始化这种数据结构,主要用于描述线程的属性和线程上下文,上下文是一个内存块,其中包含了CPU的寄存器集合。对于X86,X64和IA64的CPU来说,分别要使用700,1240和2500字节的内存。
  • 线程环境块(thread environment block,简称TEB),TEB是在用户模式(应用程序能快速访问的内存地址)中分配和初始化的一个内存块,TEB耗用1个内存页(X86和X64 CPU中是4KB,IA64 CPU是8KB)。
  • 用户模式栈(user-mode stack),用户模式栈用于存储传给方法的局部变量和实参,它还包含一个地址,指出当前方法返回时,线程接着应该从什么地方执行,默认情况下,windows为每个线程的用户模式栈分配1MB内存。
  • 内核模式栈(kernel-mode stack),当应用程序代码向操作系统中的一个内核模式的函数传递实参时,就会使用到内核模式栈。出于安全的考虑,Windowd会把这些实参从线程的用户模式栈复制到线程的内核模式栈。32windows 内核模式栈大小12KB,64位是24KB。
  • DLL线程连接(attach)和线程分离(detach)通知,Windows的一个策略是,任何时候在进程中创建线程,都会调用进程中加载的所有非托管DLL的DllMain方法,并向该方法传递DLL_THREAD_ATTACH标志。同样的,任何时候线程终止,都会调用进程中的所有非托管DLL的DllMain方法,并向该方法传递DLL_THREAD_DETACH标志。

2,时间上

因为windows要在系统中的所有线程(逻辑CPU)之间共享物理CPU。在任何给定的时刻,windows只将一个线程分配给一个CPU,那个线程能运行一个“时间片”的长度。时间片到期,Windows就将上下文切换到另一个线程。

每个时间片的切换,windows都需要大概30ms的时间。

为什么要使用多线程

1,可响应性,或称用户体验,一般针对winform程序,可以将一些耗时的任务交给另一个线程去处理,使GUI线程能灵敏地响应用户的输入和操作。否则,界面会比较卡。

2,提升性能,由于windows每个CPU调度一个线程,多个CPU能并行调度线程,所以可以同时执行多个任务,从而提升性能。

进程,线程和应用程序域的关系

在进一步学习多线程之前,很有必要来了解一下这三个概念,以及其中的关系。

1,名词解释

进程

或称Process,可以简单理解为一个.exe的实例。进程是windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。

线程

或称Thread,可以简单理解为虚拟CPU。线程是进程的基本执行单元,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。

应用程序域

或称AppDomain,可以简单理解为一组程序集的逻辑容器。CLR在初始化在初始化时创建第一个AppDomain(默认AppDomain),这个AppDomain在进程终止时被销毁。.NET的程序集正是在应用程序域中运行的。一个进程可以包含有多个应用程序域,一个应用程序域也可以包含多个程序集。

2,进程,线程和应用程序域的关系

可以用以下两幅图和两句话来总结。

1),一个进程可以包含多个线程和应用程序域。

2),一个线程可以穿梭在多个应用程序域中,但在某个时刻,线程只会处于一个应用程序域内。

前台线程和后台线程的区别

1,前台线程和后台线程的区别在于,应用程序必须运行完所有的前台线程才可以退出,而对于后台线程,可以不考虑其是否运行完而直接退出并且不会抛出异常,所有的后台线程在应用程序退出时就自动结束了。

2,默认情况下,主线程和使用Thread创建的线程都是前台线程(使用线程池和Task创建的线程默认都是后台线程),除非手动设置IsBackground= true。

多线程和异步的区别

多线程和异步在很多时候被认为是同一个东西,都是为了让主线程不需要等待而继续执行。

但是从辩证关系上来看,两者还是有区别的,可以用一句话来概括。

异步是目的,多线程是实现异步的其中的一种方式(比如还可以通过创建另一个进程实现异步)。

时间: 2024-11-10 15:40:51

多线程(1)认识多线程的相关文章

秒杀多线程第一篇 多线程笔试面试题汇总 ZZ 【多线程】

http://blog.csdn.net/morewindows/article/details/7392749 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些其它IT公司如百度,阿里巴巴的笔试面试题目,因此具有很强的针对性.系列中不但会详细讲解多线程同步互斥的各种“招式”,而且会进一步的讲解多线程同步互斥的“内功心法”.有了“招式”和“内功心法”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多线程试题. ----------------------

C#多线程学习(一) 多线程的相关概念

什么是进程?    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?    线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 什么是多线程?    多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 多线程的好处:    可以提

C#多线程学习(一) 多线程的相关概念(转)

什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 什么是多线程?多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 多线程的好处:可以提高CPU的利用率.在多线程程序中

秒杀多线程第一篇 多线程笔试面试题汇总

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些其它IT公司如百度,阿里巴巴的笔试面试题目,因此具有很强的针对性.系列中不但会详细讲解多线程同步互斥的各种“招式”,而且会进一步的讲解多线程同步互斥的“内功心法”.有了“招式”和“内功心法”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多线程试题. -------------------------------------华丽的分割线

python 多线程和C++多线程的区别

看到论坛上有人问python多线程和C++多线程的区别? 暖神是这样回答的: Python有Global Interpreter Lock,所以嘛……你懂的.C++11开始才有多线程,使用共享内存方式的线程间通信,有低级的atomic operation和memory order,以及高级的lock, condition的,却没有提供消息队列. 然后,就去找GIL(Global Interpreter Lock)的定义,下面有一个定义,wiki的定义是这样的.在stackoverflow上看到了

Unity3D游戏开发之多线程及使用多线程

Unity3D游戏开发之多线程及使用多线程 Unity3D中的多线程.线程是一个相当复杂的话题,但如果掌握了它,就可以从容的使用多个硬件处理器或处理很难划分管理数据块. 如在场景中用A*算法进行大量的数据计算,变形网格中操作大量的顶点,持续的要运行上传数据到服务器,二维码识别等图像处理,如果同时你要处理很多事情或者与Unity的对象互动小可以用thread,否则使用coroutine. 线程是在程序中与其他线程同时运行的进行.在多处理器的计算机上可以做到多个线程的真正的同步,更多的线程取决于有多

详解多线程MT和多线程MD的区别

这段时间司在招实习生,而不管是远程的电话面试或者是实际现场面试中领导都喜欢问你这个问题,但是可惜的是能很好答上来的人很少.后来发现不管是应届的实习生,甚至有些实际参加工作几年的人也未必真的了解这个问题.今天想写一篇详解,希望对广大程序员有一定的帮助. 区别1:全局堆句柄不一样. 网上有一个说法,就是一个线程一个栈,一个模块一个堆.前者很容易有理解,每个线程创建的时候在CreateThread中都能制定默认栈大小,只是很多情况下都取了默认值.而一个模块一个堆呢?其实很简单测试,如果是一个多线程MT

多线程系列(1)多线程基础和Thread

因为现项目中有用到多线程和并发的知识,所以打算近期补习一下多线程相关的内容.第一篇文章从最基础的开始,就是如何开启一个线程,如何启动线程和阻塞线程等,这篇文章分以下几点进行总结. 多线程初印象 多线程的使用场景 线程的启动,挂起和终止 一个简单的多线程实例 多线程初印象 首先通过一张图来了解一下进程Process,应用程序域AppDomain和线程Thread之间的关系. 从图中可以总结出以下几点: 一个进程Process可能包含多个应用程序域,也包含多个线程,线程也可以穿梭于多个应用程序域当中

[.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 多线程高级应用

[.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 多线程高级应用 本节要点: 上节介绍了多线程的基本使用方法和基本应用示例,本节深入介绍.NET多线程中的高级应用. 主要有在线程资源共享中的线程安全和线程冲突的解决方案:多线程同步,使用线程锁和线程通知实现线程同步. 1. ThreadStatic特性 特性:[ThreadStatic] 功能:指定静态字段在不同线程中拥有不同的值 在此之前,我们先看一个多线程的示例: 我们定义一个静态字段: static

(原创)JAVA多线程一传统多线程

一,多线程 多线程是提高程序效率,避免资源浪费的很好的解决方案,下面来慢慢的介绍多线程的一些基本知识,而这些是晋级高级不可或缺的一部分 1,Thread类 类实现多线程需要实现Runnable接口,我们跟踪一下源码,如下所示: public class Thread implements Runnable { /* Make sure registerNatives is the first thing <clinit> does. */ private static native void