线程也疯狂------线程基础

参考页面:

http://www.yuanjiaocheng.net/webapi/web-api-gaisu.html

http://www.yuanjiaocheng.net/webapi/create-web-api-proj.html

http://www.yuanjiaocheng.net/webapi/test-webapi.html

http://www.yuanjiaocheng.net/webapi/web-api-controller.html

http://www.yuanjiaocheng.net/webapi/config-webapi.html

前言

最近在做一个公司内部的分享,主要是关于线程处理方面,课程的目标是培训那些对线程理解和使用有所欠缺的开发人员,本篇文章主要介绍为什么引入线程的概念、CPU的发展趋势、线程开销、线程调度。

Windows为什么要支持线程

早期的操作系统是没有线程概念的,整个系统只运行一个执行线程,其中包含了系统代码和程序代码。只用一个执行线程的问题在于,长时间的运行任务会阻止其他任务执行,有些应用程序的bug会造成死循环,同样会造成整个机器停止工作,针对这个问题用户只好重启计算机。在这种迫切的需求下,微软计划构建一个新的OS来满足企业和个人的需要,新的OS必须健壮、可靠、易于伸缩和安全。

进程和线程的概念

进程实际是应用程序的实例要使用的资源的集合,每个进程都被赋予了一个虚拟的地址空间,确保在一个进程中使用的代码和数据无法由另一个进程访问。这样就确保了程序的健壮性,此外进程也无法访问OS的系统代码,使得操作系统更加稳定和安全。

但是对于CPU呢? 应用程序会死循环执行吗?如果安装上面所说,机器只有一个cpu,它会执行死循环,不能执行其他任何东西,虽然数据无法被破坏,而且更加安全但是系统仍然可能停止响应,微软针对这种问题,解决的方案就是线程。

线程职责:对CPU进行虚拟化,Windows为每个进程都提供了该进程专用的线程,如果应用程序的代码进入死循环,与那个代码关联的进程会冻结,但其他进程仍会继续执行。

线程开销

同一切虚拟化机制一样,线程有空间(内存)和时间(性能)上的开销:

1. 线程内核对象

通俗的讲就是线程的数据结构,主要包括:线程描述、线程上下文(CPU寄存器集合的内存块),不同的架构对应的线程上下文使用的字节也不同

2. 线程环境块(TEB)

TEB是在用户模式中分配和初始化的内存块,大约1个内存页4kb,主要包括:线程异常处理链首、线程本地存储数据以及由GDI和OpenGL图形使用的一些数据结构

3. 用户模式栈

存储传给方法的局部变量和实参。

4. 内核模式栈

验证用户模式栈中的参数的值。

5. DLL线程连接和线程分离通知

调用所有于线程有关操作(创建、终止等)的非托管DLL的DLLMain方法,并向方法传递ATTACH标志。

线程上下文

Windows任何时刻只将一个线程分配给CPU,每个线程只能运行一个时间片的长度,时间片到期,Windows就上下文切换到一另外一个线程,每次切换线程的操作:

1. 将CPU寄存器的值保存到当前正在运行的线程的内核对象内部的一个上下文结构

2. 从现有线程集合中选出一个线程提供调度

3. 将所选上下文结构中的值加载到CPU的寄存器中

上下文切换完成后,CPU执行所选的线程,直到它的时间片到期。上下文的切换对性能的影响非常大,而且切换所需的时间取决于CPU架构和速度,填充CPU缓存所需要的时间取决于操作系统中运行的程序、CPU缓存的大小以及其他各种因素,所以无法为每一次上下文的开销给出确定的值,所以要构建搞性能的应用程序和组件,尽量避免上下文切换。

线程调度和优先级

Windows之所以被成为抢占式多线程操作系统,是因为线程可在任何时间停止并调度另一个线程,每个线程都分配了从0到31的优先级,系统决定为CPU分配哪个线程时,首先检查优先级为31的线程,并通过轮流方式调度它们,如果优先级31的一个线程可以调度,就把它分配给CPU。在这个线程的时间片结束时,系统检查是否有另一个优先级31的线程可以运行。

只要存在可调度的优先级31的线程,系统就永远不会将<31的任何线程分配给CPU,这种情况称之为饥饿。

进程优先级类:Idle,Below Normal,Normal,Above Normal,High,Realtime. 默认为Normal

前台线程和后台线程

一个进程的所有前台线程停止运行时,CLR强制终止仍在运行的任何后台线程。

本篇主要是讲解线程的基础知识理论过多可能会枯燥,总的来说线程是非常宝贵的资源,必须省着使用,为了做到这一点,最好的方式就是使用CLR的线程池,线程池为你自动管理线程的创建和销毁。下篇会继续讲解,计算限制的异步操作,结合实际案例了解异步操作的优点。

时间: 2024-11-11 14:49:58

线程也疯狂------线程基础的相关文章

线程也疯狂-----异步编程

前言 本节主要介绍异步编程中Task.Async和Await的基础知识. 什么是异步? 异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程. 异步和多线程 相同点:避免调用线程阻塞,从而提高软件的可响应性. 不同点: 异步操作无须额外的线程负担,并且使用回调的方式进行处理,在设计良好的情况下,处理函数可以不必使用共享变量(即使无法完全不用,最起码可以减少 共享变量的数量),减少了死锁的可能.C#5.0 .NET4.5 以后关键字Async和Awai

线程也疯狂------计算限制的异步操作

参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1.html http://www.yuanjiaocheng.net/webapi/create-crud-api-1-get.html http://www.yuanjiaocheng.net/webapi/create-crud-api-1-post.html http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.

001-多线程基础-进程线程、线程状态、优先级、用户线程和守护线程

一.进程与线程 1.DOS系统[单进程系统] 最早的时候DOS有一个特点:只要电脑有病毒,那么电脑就死机了. 原因:传统的DOS系统属于单进程系统,即:在同一时间段内只允许有一个程序运行. 2.Windows系统[多进程多线程] 电脑中毒也可以运行,但是会变慢 原因:因为在一个cpu.一块资源的情况下,程序利用一些轮转算法,可以让一个资源在一个时间段可以同时处理多个程序(进程),但是在一个时间点上只允许一个进程去执行. windows:任务管理器 linux:ps 在每一个进程上可以划分出若干个

基础线程机制--Executor线程池框架

基础线程机制 Executor线程池框架 1.引入Executor的原因 (1)new Thread()的缺点 ???每次new Thread()耗费性能 ???调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,之间相互竞争,导致过多的系统资源被占用导致系统瘫痪,不利于定时执行,定期执行,线程中断. (2)采用线程池的优点 ???可以重用创建的线程,减少对象的创建,消亡的开销,性能更佳. ???可以有效的控制最大并发线程数,提高系统资源的利用率,避免过多的资源竞

Java并发编程(02):线程核心机制,基础概念扩展

本文源码:GitHub·点这里 || GitEE·点这里 一.线程基本机制 1.概念描述 并发编程的特点是:可以将程序划分为多个分离且独立运行的任务,通过线程来驱动这些独立的任务执行,从而提升整体的效率.下面提供一个基础的演示案例. 2.应用案例 场景:假设有一个容器集合,需要拿出容器中的每个元素,进行加工处理,一般情况下直接遍历就好,如果数据偏大,可以根据线程数量对集合切割,每个线程处理一部分数据,这样处理时间就会减少很多. public class ExtendThread01 { publ

java 线程 --- Thread,Runnable,Callable 基础学习

java 使用 Thread 类代表线程,所有现场对象都必须是 Thread 类或者其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流.java 使用线程执行体来代表这段程序流. 1.继承Thread 类创建线程 启动多线程的步骤如下: (1)定义Thread 类的子类,并重写该类的run() 方法,该run() 方法的方法体就代表类线程需要完成的任务.因此把run() 方法称为线程执行体. (2)创建 Thread 子类的实例,即创建线程对象. (3)调用线程的star()

【Java基础】Java多线程之线程组和线程池

在上一篇文章中,讲述了线程的基本概念和用法,这里将继续讲述线程组和线程池的一些东西. 线程组:java.lang.ThreadGroup 1. 线程组的介绍 线程组表示一个线程的集合.此外,线程组也可以包含其他线程组.线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组.允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息.   2. 线程组的构造方法 ThreadGroup(String name) 构造一个新线程组. Thread

黑马程序员——JAVA基础之Day24 多线程 ,死锁,线程间通信 ,线程组,线程池,定时器。

------- android培训.java培训.期待与您交流! ---------- Lock()实现提供了比使用synchronized方法和语句可获得更广泛的锁定操作. private Lock lock =new ReentrantLock(); 被锁的代码要用   lock.lock()                lock.unlock()    包括.其中用try   ...finally包围 同步:效率低,如果出现同步嵌套,会出现死锁.  但是安全. 死锁问题:两个或者两个以上

java8--多线程(java疯狂讲义3复习笔记)

多线程这块,平时用的框架里都封装好了,只有写批处理和工具包时用过几次.现在水平仅仅限于会用的程度,需要全面深入学习多线程. 主要内容:创建线程,启动线程,控制线程,多线程的同步,线程池,使用线程安全的集合类 16.1.1 线程和进程 线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程.线程可以拥有自己的堆栈,程序计数器和局部变量,但不拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源.因为多个线程共享父进程的全部资源,因此编程更加方便,带也需要更加小心. 16.2