本地线程

.net中ThreadPool与Task的认识总结

萝らか妹 提交于 2020-01-02 05:35:52
线程池和Task是多线程编程中两个经常使用的技术,大家在熟悉不过了。他们有什么关联关系?Task又是怎么工作的呢?估计很多时候会犯糊涂。通过翻阅资料,终于弄明白了,与大家分享一下。 工作线程与I/O线程 在ThreadPool中有这样一个方法: public static bool SetMaxThreads(int workerThreads, int completionPortThreads); 此方法中有两个参数:workerThreads和completionPortThreads。这两个参数引申出了两个概念:辅助线程(也叫工作线程)和异步 I/O 线程。这两个线程有什么区别么?通过查阅资料,我们可以了解到,工作线程其实就是我们编码主动向ThreadPool中创建的线程。而I/O线程是线程池中预先保留出来的部分线程,这部分线程的作用是为了分发从IOCP(I/O completion port) 中的回调。 那么什么是IOCP回调呢? 在CLR内部,系统维护了一个IOCP(I/O completion port),它提供了处理多个异步I/O请求的线程模型。我们可以把IOCP看做是一个消息队列。当一个进程创建了一个IOCP,即创建了一个队列。当异步I/O请 求完成时,设备驱动程序就会生成一个I/O完成包,将它按照FIFO方式排队列入该完成端口。之后,会由I/O线程提取完成I

Java 内存区域详解

纵饮孤独 提交于 2020-01-02 00:30:02
一.概述 因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。 二.运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它管理的 内存划分成若干个不同的数据区域 。JDK. 1.8 和之前的版本略有不同。 JDK1.8之前: JDK1.8: 线程私有的:程序计数器、虚拟机栈、本地方法栈 线程共享的:堆、方法区、直接内存(非运行时数据区的一部分) JDK8 将方法区从运行时数据区移到直接内存,并改名为元空间 1.程序计数器 程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。 字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。 另外, 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。 从上面的介绍中我们知道程序计数器主要有两个作用: 字节码解释器通过改变程序计数器来 依次读取指令 ,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。 在多线程的情况下,程序计数器 用于记录当前线程执行的位置

多线程学习:Volatile与Synchronized的区别、什么是重排序

大城市里の小女人 提交于 2020-01-01 17:37:25
java线程的内存模型   java的线程内存模型中定义了每个线程都有一份自己的共享变量副本(本地内存),里面存放自己私有的数据,其他线程不能直接访问,而一些共享变量则存在主内存中,供所有线程访问。 上图中,如果线程A和线程B要进行通信,就要经过主内存,比如线程B要获取线程A修改后的共享变量的值,要经过下面两步: (1)、线程A修改自己的共享变量副本,并刷新到了主内存中。 (2)、线程B读取主内存中被A更新过的共享变量的值,同步到自己的共享变量副本中。 总结:在java内存模型中,共享变量存放在主内存中,每个线程都有自己的本地内存,当多个线程同时访问一个数据的时候,可能本地内存没有及时刷新到主内存,所以就会发生线程安全问题。 java多线程中的三个特性:   原子性: 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。一个很经典的例子就是银行账户转账问题:比如从账户A向账户B转1000元,那么必然包括2个操作:从账户A减去1000元,往账户B加上1000元。这2个操作必须要具备原子性才能保证不出现一些意外的问题。   可见性: 当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。   有序性: 就是 程序执行的顺序按照代码的先后顺序执行。 一般来说处理器为了提高程序运行效率,可能会对输入代码进行优化

从三个特性理解多线程开发

岁酱吖の 提交于 2020-01-01 17:37:10
工作中许多地方需要涉及到多线程的设计与开发,java多线程开发当中我们为了线程安全所做的任何操作其实都是围绕多线程的三个特性:原子性、可见性、有序性展开的。针对这三个特性的资料网上已经很多了,在这里我希望在站在便于理解的角度,用相对直观的方式阐述这三大特性,以及为什么要实现和满足三大特性。 一、原子性 原子性是指一个操作或者一系列操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。其实这句话就是在告诉你,如果有多个线程执行相同一段代码时,而你又能够预见到这多个线程相互之间会影响对方的执行结果,那么这段代码是不满足原子性的。结合到实际开发当中,如果代码中出现这种情况,大概率是你操作了共享变量。 针对这个情况网上有个很经典的例子,银行转账问题: 比如A和B同时向C转账10万元。如果转账操作不具有原子性,A在向C转账时,读取了C的余额为20万,然后加上转账的10万,计算出此时应该有30万,但还未来及将30万写回C的账户,此时B的转账请求过来了,B发现C的余额为20万,然后将其加10万并写回。然后A的转账操作继续——将30万写回C的余额。这种情况下C的最终余额为30万,而非预期的40万。 如果A和B两个转账操作是在不同的线程中执行,而C的账户就是你要操作的共享变量,那么不保证执行操作原子性的后果是十分严重的。 OK,上面的状况我们理清楚了,由此可以引申出下列三个问题 1

【Java多线程】Executor框架的详解

安稳与你 提交于 2020-01-01 10:16:03
在Java中,使用线程来异步执行任务。Java线程的创建与销毁需要一定的开销,如果我们为每一个任务创建一个新线程来执行,这些线程的创建与销毁将消耗大量的计算资源。同时,为每一个任务创建一个新线程来执行,这种策略可能会使处于高负荷状态的应用最终崩溃。 Java线程既是工作单元,也是执行单元。从JDK1.5开始,把工作单元与执行机制分离开来。工作单元包括Runnable 和 Callable,而执行机制由Executor框架提供。 Executor框架简介 Executor框架的两级调度模型 在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当Java线程终止时,这个操作系统线程也会被回收。操作系统会调用所有线程并将他们分配给可用的CPU。 可以将此种模式分为两层,在上层,Java多线程程序通常把应用程序分解为若干任务,然后使用用户级的调度器(Executor框架)讲这些任务映射为固定数量的线程;在底层,操作系统内核将这些线程映射到硬件处理器上。 两级调度模型的示意图: 从图中可以看出,该框架用来控制应用程序的上层调度(下层调度由操作系统内核控制,不受应用程序的控制)。 Executor框架的结构和成员 Executor框架的结构 1. 任务 包括被执行任务需要实现的接口

Visual C++ 11 中新的并发功能

岁酱吖の 提交于 2020-01-01 02:47:12
最新的 C++ 迭代(称为 C++11,在去年通过了国际标准化组织 (ISO) 的审批)形式化了一组新库和一些保留字以处理并发。 许多开发者以前都在 C++ 中使用过并发功能,但都是通过第三方的库,即,通常直接公开 OS API。 Herb Sutter 在 2004 年 12 月宣告“免费的性能午餐”结束,因为禁止 CPU 制造商通过物理能耗和增加碳排放量来生产更快的 CPU。 由此进入了当前主流的多核时代,一种新的实现,而 C++(标准组件)为适应此类变化取得了重要的飞跃。 本文下面的内容将分成两节,另外还有一些小节。 第一节,从并行执行开始,介绍允许应用程序并行运行独立或半独立活动的技术。 第二节,从同步并发执行开始,探讨同步机制,这些活动通过同步方式处理数据,以避免出现争用情况。 本文基于即将推出的 Visual C++ 版本(现在称为 Visual C++ 11)中包括的功能。 当前版本 (Visual C++ 2010) 中已提供其中部分功能。 尽管本文不提供关于为并行算法建模的指南,也不提供关于所有可用选项的详尽文档,但却全面介绍了新的 C++11 并发功能,内容丰富详实。 并行执行 当您对数据建模和设计算法时,很自然地就会按照具有一定顺序的步骤指定这些建模和设计过程。 只要性能位于可接受的范围内,这就是最值得推荐的方案,因为它通常更易于理解,而这符合维护代码的要求。

Visual Studio 11增强支持的标准 C++11 介绍

吃可爱长大的小学妹 提交于 2020-01-01 02:45:49
Visual Studio 11增强支持的标准 C + + 11 现在支持此预览的 Visual Studio 的 STL 中的新头文件可以进行多线程编程和异步操作管理。 <thread>,<future>,<atomic>,<time>,<mutex>,<condition_variable>,<ratio>,<filesystem> 头文件<thread>作为其名称来创建和操作线程 1.thread t([]() 2. { 3. cout << "ThreadID : " << std::this_thread::get_id() << endl; 4. }); 5. t.join(); 1.thread t([]() 2. { 3. cout << "ThreadID : " << std::this_thread::get_id() << endl; 4. }); 5. t.join(); 这是传递给线程的类的构造函数的一种方法,而不是在这里我们使用Lambda 表达式中引入C + + 11Join ()方法,这是一个调用阻塞,使主线程等待,直到线程完成他的工作。如果要解耦变量的类型线程,线程在 Windows 那里 调用 的detach()方法,这样做违背计划的detach()方法,不会影响与线程句柄关联的窗口 (CloseHandle)。因此可能是使用变量的 t 型线

Visual C++ 11 中新的并发功能

£可爱£侵袭症+ 提交于 2020-01-01 02:44:36
最新的 C++ 迭代(称为 C++11,在去年通过了国际标准化组织 (ISO) 的审批)形式化了一组新库和一些保留字以处理并发。 许多开发者以前都在 C++ 中使用过并发功能,但都是通过第三方的库,即,通常直接公开 OS API。 Herb Sutter 在 2004 年 12 月宣告“免费的性能午餐”结束,因为禁止 CPU 制造商通过物理能耗和增加碳排放量来生产更快的 CPU。 由此进入了当前主流的多核时代,一种新的实现,而 C++(标准组件)为适应此类变化取得了重要的飞跃。 本文下面的内容将分成两节,另外还有一些小节。 第一节,从并行执行开始,介绍允许应用程序并行运行独立或半独立活动的技术。 第二节,从同步并发执行开始,探讨同步机制,这些活动通过同步方式处理数据,以避免出现争用情况。 本文基于即将推出的 Visual C++ 版本(现在称为 Visual C++ 11)中包括的功能。 当前版本 (Visual C++ 2010) 中已提供其中部分功能。 尽管本文不提供关于为并行算法建模的指南,也不提供关于所有可用选项的详尽文档,但却全面介绍了新的 C++11 并发功能,内容丰富详实。 并行执行 当您对数据建模和设计算法时,很自然地就会按照具有一定顺序的步骤指定这些建模和设计过程。 只要性能位于可接受的范围内,这就是最值得推荐的方案,因为它通常更易于理解,而这符合维护代码的要求。

并发技术、进程、线程和锁拾遗

点点圈 提交于 2020-01-01 00:48:07
并发技术、进程、线程和锁拾遗 Part1. 多任务 计算机发展起初,CPU 资源十分昂贵,如果让 CPU 只能运行一个程序那么当 CPU 空闲下来(例如等待 I/O 时),CPU 资源就会被浪费,为了使 CPU 资源得到更好的利用,先驱编写了一个监控程序,如果发现某个程序暂时无需使用 CPU 时,监控程序就把另外的正在等待 CPU 资源的程序启动起来,以充分利用 CPU资源。这种方法称为 - 多道程序(Multiprogramming) 对于多道程序,最大的弊端是各程序之间不区分轻重缓急,对于用户交互式的程序来说,对 CPU 计算时间的需求并不多,但是对于响应速度却有比较高的要求。而对于计算类程序来说则相反,对响应速度要求低,但需要长时间的 CPU 计算。想象一个场景:我在同时在浏览网页和听音乐,我们希望浏览器能够快速响应,同时也希望音乐不停,这时候 多道程序 就没法达到我们的要求了。 于是人们改进了 多道程序 ,使得每个程序运行一段时间之后,都主动让出 CPU 资源,这样每个程序在一段时间内都有机会运行一小段时间。这样像浏览器这样的交互式程序就能够快速地被处理,同时计算类程序也不会受到很大影响。这种程序协作方式被称为 分时系统(Time-Sharing System) 。 在分时系统的帮助下,我们可以边用浏览器边听歌了。 但是 如果某个程序出现了错误,导致了死循环

jvm系列(一)之内存模型

£可爱£侵袭症+ 提交于 2019-12-31 23:02:53
JVM内存结构 Java内存模型是指Java虚拟机的内存模型,我们来看下Java内存模型的图片: VM内存模型主要分为三块:Java 堆内存(Heap)、方法区(Non-Heap)、JMV栈(JVM Stack)、本地方法栈(Native Method Stacks)、程序计数器(Program Counter Register)。 Java堆(Heap) 对于大多数应用来说,Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。 Java堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC堆”。如果从内存回收的角度看,由于现在收集器基本都是采用的分代收集算法,所以Java堆中还可以细分为:新生代和老年代;再细致一点的有Eden空间、From Survivor空间、To Survivor空间等。 根据Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。 如果在堆中没有内存完成实例分配,并且堆也无法再扩展时