线程

《windows核心编程》- 线程栈

 ̄綄美尐妖づ 提交于 2020-04-07 03:10:47
当系统创建线程的时候,会为线程栈预订一块地址空间区域,并给该区域调拨一些物理存储器。默认会预订1MB的地址空间并调拨两个页面的存储器。但是在构建 应用程序的时候可以改变这个默认值 在构建应用程序的时候链接器会把栈的大小写入到exe和dll文件的pe文件头中,当创建线程的时候会根据PE文件头中的大小来预订空间区域。在调用CreateThread或_beginthreadex的时候开发人员可以指定需要在一开始就调拨的地址空间大小和存储器大小。 下面显示了一台页面大小为4KB的机器上线程栈的地址空间区域(基址为0x08100000 )。该线程栈的地址空间区域和所调拨给该区域的都具有PAGE_READWRITE保护属性。 在预订地址空间后,系统会给区域顶部的两个页面调拨物理存储器。在线程开始之前系统会把线程栈的指针指向最上面那两个页面的末尾。这个页面就是线程开始使用栈的地方。区域顶部往下的第二个页面被称为防护页面。随着调用的越来越多,调用树也越来越深,线程也需要越来越多的栈空间 当线程试图访问防护页中的内存时,系统会得到通知这时系统会先给防护页面下面的那个页面调拨存储器,接着去除当前防护页面的PAGE_GUARD保护属性标志,然后给刚调拨的存储页指定PAGE_GUARD保护属性标志。该项技术使得系统能够在线程需要的时候才增加栈存储器大小。如果线程的调用树 断加深

多线程学习笔记一

戏子无情 提交于 2020-04-07 02:25:23
关于线程的常见问题- 什么是并发与并行? 并行:两个或者多个事件在同一时刻发生 并发:两个或者多个事件在同一个时间段内发生 什么是进程与线程? 进程是正在运行的程序的实例 进程是线程的容器,一个进程可以开启多个线程 比如打开一个浏览器,会创建进程 线程如何创建? 继承Thread类 实现Runnable接口 实现Callable接口鸭 从线程池-Excutor 获取线程 实现类接口和继承类接口的比较:    接口更适合多个相同的程序代码去共享同一个资源   接口可以避免java中单继承的局限性   接口代码可以被多个线程共享,代码和线程独立   线程池只能 放入实现Runnable和Callable接口的线程,不能直接放入继承Thread的线程    java中,每次运行程序至少启动2个线程,一个是main线程,一个是垃圾收集线程 线程的生命周期? 什么是线程安全问题?线程安全问题解决方案? 线程安全问题都是由全局变量及静态变量引起的 若每个线程对全局变量,静态变量只读,不写,则这个变量是线程安全的 若有多个线程同时执行写操作,则需要考虑线程同步,否则就可能影响线程安全      解决方案 :线程同步 - 只要在某个线程修改共享资源的时候,其他线程不能修改该资源,等待修改完毕同步之后,才能去抢夺资源,完成对应的操作,保证了数据的同步性。 java引入了7种同步机制: 同步代码块

单核cpu多线程有必要吗?

こ雲淡風輕ζ 提交于 2020-04-07 01:32:08
问题分析 现代计算机一般都是多核cpu,多线程的可以大大提高效率,但是可能会有疑问,那单核CPU使用多线程是不是没有必要了,假定一种情况, web应用服务器,单核CPU、单线程 ,用户发过来请求,单个线程处理,CPU等待这个线程的处理结果返回,查询数据库,CPU等待查询结果...,只有一个线程的话,每次线程在处理的过程中CPU都有大量的空闲等待时间,那这样来说并行和串行似乎并没有体现并行的优势,因为任务的总量在那里,实际情况肯定不是这样的,即便是单核CPU,一个进程中往往也是有多个线程存在的,每个线程各司其职,CPU来调度各线程。 这里需要区分CPU处理指令和IO读取的不同,CPU的执行速度要远大于IO的过程,因此在大多数情况下多一些复杂的CPU计算都比增加一次IO要快,这一块深入理解要学习计算机原理相关的知识。 现实生活中也是有很多类似的例子,比如厨师做一道菜,买菜和买配料需要去不同的两个商店,如果这个过程只依靠他一个人来做,那耗费的总时间就是买菜再去买调料的总时间,如果有一个帮厨,那么就可以兵分两路,再来汇总结果,时间基本可以减半,厨师和帮厨就是不同的线程。 编程是高度抽象生活的一门艺术。 场景模拟 模拟单线程和多线程的效率差距,这里使用连接数据库,和读取磁盘文件来模拟IO操作,期望结果: 单线程总耗时:数据库连接耗时 + 磁盘文件读取耗时 多线程总耗时

Go语言进阶学习笔记

╄→гoц情女王★ 提交于 2020-04-07 00:46:54
协程 创建时默认的 stack 的⼤⼩ JDK5 以后 Java Thread stack 默认为1M Groutine 的 Stack 初始化⼤⼩为2K 和 KSE (Kernel Space Entity 系统线程) 的对应关系 Java Thread 是 1:1 Groutine 是 M:N Thread 切换代价大 先说,协程的本质是用户态的线程,用户对其有控制权限,内存占用少,切换代价低。 再来解释一下MPG是什么意思。 M代表内核线程,所有的G都要放在M上才能运行。 P代表控制器,调度G到M上,其维护了一个队列,存储了所有需要它来调度的G。 G代表一个go routine单元。 补充几点常见的调度策略: 1,如果某个M陷入阻塞呢? 当一个OS线程M由于io操作而陷入阻塞,假设此时G0正跑在了M上,那么M上绑定的P就会带着余下的所有G去寻找新的M。当M恢复过来时,一般情况下,会从别的M上拿过来一个P,并把原先跑在其上的G0放到P的队列中,从而运行G0。如果,没有拿到可用的P的话,就把G0放入到全局global runqueue队列中,使G0等待被调度,然后M进入线程缓存。所有的P也会周期性的检查global runqueue并运行其中的goroutine,否则global runqueue上的goroutine永远无法执行。 2,如果有的M较忙,有的M较闲呢?

CPU上下文切换

北城余情 提交于 2020-04-06 23:50:43
CPU上下文 在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)。 CPU 寄存器,是 CPU 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 CPU 在运行任何任务前,必须的依赖环境,因此也被叫做 CPU 上下文。 CPU 上下文切换 就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来 加载新任务的上下文到这些寄存器和程序计数器 跳转到程序计数器所指的新位置,运行新任务。 根据任务的不同,CPU 的上下文切换就可以分为几个不同的场景,也就是进程上下文切换、线程上下文切换以及中断上下文切换。 进程和线程 进程是资源分配和执行的基本单位;线程是任务调度和运行的基本单位。线程没有资源,进程给指针提供虚拟内存、栈、变量等共享资源,而线程可以共享进程的资源。 进程上下文切换 Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间。 CPU 特权等级的 Ring 0 和 Ring 3。 内核空间(Ring 0)具有最高权限,可以直接访问所有资源;用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中

不会这年头还有人不知道OPPO Android 开发技术面吧,年薪百万的大牛都在看了

旧巷老猫 提交于 2020-04-06 23:49:34
今天早上参加了深圳 OPPO 开发工程师的技术面试,总的来说面试过程不是很顺利。面试官并没有问一些很深奥的底层原理,基本都是一些 Java 基础以及 Android 四大组件内的基础,但是我自身在开发过程中并没有很重视这些理论基础,导致很多知识点都忘记了。整个面试过程耗时一小时,感谢两位面试官不厌其烦地给我提示,一方面让我能够回想起来那些遗忘的知识点,另一方面也缓解了尴尬的气氛。。。 顺便一说,OPPO 的保密工作还是做得比较严格的,进去后海卓越中心大楼前需要申请临时通行证才能进去。而在面试前还需要登记,并且把手机的前后摄像头都给用胶带封起来才能进行面试。废话少说,下面分成两部分汇总一下这次技术面试的知识点。 Java 1. 如何理解Java的多态?其中,重载和重写有什么区别? 多态是同一个行为具有多个不同表现形式或形态的能力,多态是同一个接口,使用不同的实例而执行不同操作,多态就是程序运行期间才确定,一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法。多态存在的三个必要条件是:继承,重写,父类引用指向子类引用。多态的三个实现方式是:重写,接口,抽象类和抽象方法。 重写(Override)和重载(Overload)的区别 区别点重载重写参数列表必须修改不能修改返回类型可以修改不能修改异常可以修改可以减少或删除

进程创建的过程

吃可爱长大的小学妹 提交于 2020-04-06 22:05:14
1.什么是进程?   进程提供程序所需的资源,如: 数据、代码等等(空间上的概念) 进程由一大堆PE格式文件组成。 3.进程的创建 <1>任何进程都是别的进程创建的:CreateProcess() <2>进程的创建过程 映射EXE文件 创建内核对象EPROCESS 映射系统DLL(ntdll.dll) 创建线程内核对象ETHREAD 系统启动线程     映射DLL(ntdll.LdrlnitializeThunk)   线程开始执行 注意每个进程里至少一个线程,一个EPROCESS结构体和ETHREAD结构体 来源: https://www.cnblogs.com/hanhandaren/p/11114864.html

Android知识体系总结2020之Android部分Handler篇

江枫思渺然 提交于 2020-04-06 22:02:22
1.什么是Handler?   Handler是可以通过发送和处理Message和Runnable对象来关联相应线程的MessageQueue。通常我们认为它是一种异步机制。   a.可以让对应的Message和Runnable在未来的某个时间点进行相应的处理。   b.让自己想要的耗时操作在子线程中完成,让更新UI的操作在主线程中完成,而子线程与主线程之间的通信就是靠Handler来完成。 2.Handler的使用方法   Handler提供了很多异步机制的方法,只不过我们常用就只有post和sendMessage系列方法,我们先来看看Handler提供的构造器吧: Handler():默认构造函数将此处理程序与Looper用于当前线程。 Handler(Handler.Callback callback):构造函数将此处理程序与Looper对于当前线程,并接受一个回调接口,您可以在其中处理消息。 Handler(Looper looper):使用所提供的Looper而不是默认的。 Handler(Looper looper, Handler.Callback callback):使用所提供的Looper而不是默认的,而是接受一个回调接口来处理消息。   接下来我们就来看看Handler提供的各种方法吧: post(Runnable r):导致将Runnable

这样终止线程,竟然会导致服务宕机?

喜夏-厌秋 提交于 2020-04-06 21:50:08
在开始之前,我们先来看以下代码会有什么问题? public class ThreadStopExample { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { try { System.out.println("子线程开始执行"); // 模拟业务处理 Thread.sleep(1000); } catch (Exception e) { } // 伪代码:重要的业务方法 System.out.println("子线程的重要业务方法"); }); t1.start(); // 让子线程先运行一点业务 Thread.sleep(100); // 终止子线程 t1.stop(); // 等待一段时间,确保子线程“执行完” Thread.sleep(3000); System.out.println("主线程执行完成"); } } 或许你已经发现了,上面这段代码使用了 Thread.stop() 来终止线程,在 Java 程序中是不允许这样终止线程的。什么?你问为什么不能这样? 首先来说 IDE 都会鄙视你了,它会阻止你使用 Thread.stop() ! 什么?你不信。那么来看这张图: 好吧,那为什么不能这样用呢

Python数据库连接池DBUtils

梦想的初衷 提交于 2020-04-06 21:26:11
DBUtils是Python的一个用于实现数据库连接池的模块。 下载地址 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程再次使用。当线程终止时,连接自动关闭。 POOL = PersistentDB( creator=pymysql, # 使用链接数据库的模块 maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."] ping=0, # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always closeable=False, # 如果为False时, conn.close() 实际上被忽略,供下次使用,再线程关闭时,才会自动关闭链接。如果为True时, conn.close()则关闭链接,那么再次调用pool.connection时就会报错,因为已经真的关闭了连接