中断处理

ES6之Generator和async

不羁的心 提交于 2019-12-22 19:36:33
目录 一、概述 二、Generator函数 1. 基本原理 2. 使用语法 (1)yield表达式 (2)yield*表达式 (3)for ... of循环 (4)return和throw 3. Generator函数的异步应用 三、async函数 1. 基本原理 2. 语法规范 (1)await命令 (2)错误处理 总结 一、概述 Generator和async是ES6提供的新的异步解决方案。 Generator函数可以理解为一个可以输出多个值的状态机。它的返回值是一个遍历器对象(Iterator),每次调用该遍历器的next方法就会输出一个值。当有多个异步操作需要按序执行时,只要在完成一个时调一次next方法即可执行下一个。不过想要自动化执行Generator函数则需要借助一些工具。 async函数则是Generator函数的语法糖,它为Generator函数内置了自动执行器。用async函数写出的异步代码几乎与同步代码没有什么差别,使用async函数,不需要任何外部工具,即可写出格式优雅的异步代码。 总的来说,Generator函数定义了一种新的异步模型,而async函数通过对该模型的再封装,提供了一种优雅的异步解决方案。 下面我们分别对两者展开详细探讨。 二、Generator函数 1. 基本原理 众所周知,在JavaScript中,任何函数最多只能有一个返回值

多线程5一AbstractQueuedSynchronizer源码分析一

走远了吗. 提交于 2019-12-22 09:28:15
AQS的源码分析 <一> 文章目录 前言 1、什么是CAS ? 2、同步器类结构 3、CLH同步队列 4、AQS中静态内部类Node 5、方法分析 5.1、acquire(int arg ) 5.2、release(int arg) 释放锁 6、总结 前言 在多线程环境下,我们一般会对临界区资源(共享资源)进行加锁,释放锁,保证同一时刻最多只有一个线程(独占模式),就如去公共厕所里,在使用一个小房间时会加锁避免自己在使用的时候,别人突然闯进来一样,引起不必要的麻烦,在使用完后,再打开锁,其他人才可使用;还有生产者消费者模型中,线程之间要同步,需要等待和通知机制,来协调线程合作。那么这些是这么实现的?如可重入锁ReentrantLock, 读写锁ReadWriteLock, 信号量 Semaphore, 计数器CountDownLatch,这些都会涉及线程之间的协调同步,那么会有一个抽象的结构,将这些需要共用的功能抽离出来,统一来满足要求吗?我们一起来看看AbstractQueuedSynchronizer 这个抽象类,如何来实现这些功能和其设计的巧妙, 我们能看到Doug lea 大佬在很多地方使用的循环CAS操作(自旋锁)。 1、什么是CAS ? CAS 即 compare and swap 比较并交换, 涉及到三个参数,内存值V, 预期值A, 要修改的新值B,

嵌入式操作系统进入临界区是否影响中断的接受?

空扰寡人 提交于 2019-12-21 05:52:15
在ucos,Freertos中常常会有进入临界区,以保证当前的操作不可被打断,确保操作关键代码的安全。 进入临界区 关键代码操作 假设发生A类型中断 退出临界区 那么A中断还能够接受到吗? 进入临界区,关闭中断,中断发生,打开中断,这个过程中会发生什么呢? 显然,关闭中断期间,CPU不可能去响应中断,再次打开中断的时候,如果在关闭中断期间,发生了中断,发生的中断被记录下来,开启中断时候,中断控制器会再次响应这些被记录的中断。 STM32在使用时有时需要禁用全局中断,比如MCU在升级过程中需禁用外部中断,防止升级过程中外部中断触发导致升级失败。 ARM MDK中提供了如下两个接口来禁用和开启总中断: __disable_irq(); // 关闭总中断 __enable_irq(); // 开启总中断 但测试发现这样一个问题,在关闭总中断后,如果有中断触发,虽然此时不会引发中断,但在调用__enable_irq()开启总中断后,MCU会立即处理之前触发的中断。这说明__disable_irq()只是禁止CPU去响应中断,没有真正的去屏蔽中断的触发,中断发生后,相应的寄存器会将中断标志置位,在__enable_irq()开启中断后,由于相应的中断标志没有清空,因而还会触发中断。所以要想禁止所有中断,必须对逐个模块的中断进行Disable操作,由于每个模块中断源有很多

STM32之系统滴答定时器

拥有回忆 提交于 2019-12-21 04:09:19
一、SysTick(系统滴答定时器)概述   操作系统需要一个滴答定时器周期性产生中断,以产生系统运行的节拍。在中断服务程序里,基于优先级调度的操作系统会根据进程优先级切换任务,基于时间片轮转系统会根据时间片切换任务。总之,滴答定时器是一个操作系统的“心跳”。   Cortex-M3在内核部分封装了一个滴答定时器--SysTick,在之前的ARM内核通常是不会把定时器做进内核,定时器都是SOC厂商自己制作的外设。显然,Cortex-M3封装了这么一个定时器,对于将操作系统移植到不同SOC厂商生产的Cortex-M3系类MCU上,带来了极大的方便。Cortex-M3内核统一了这样的一个系统滴答定时器,移植操作系统的时候可以使用内核的定时器,而忽略掉不同厂商生产定时器带来的分歧。 二、SysTick control and status register(STK_CTRL)   SysTick的控制是极其简单的,它的控制和状态都汇聚在同一个寄存器STK_CTRL上。   STK_CTRL的每一位的含义英文解释都是很清晰的,不必多说。需要额外讨论的是COUNTFLAG标志位,这个标志位代表的含义是:当计数为0时,也即STK_VAL计数至0时,此标志位置1。   经过笔者一番摸索,对此位有更多的看法。 COUNTFLAG:    1、此位与SysTick的中断无关,不是中断标志位

Linux 内核 - 中断

我们两清 提交于 2019-12-21 01:13:31
文章目录 中断和异常 中断处理程序 中断上下文 中断和异常 中断使得硬件能够发出通知给处理器。 每个中断都通过一个唯一的数字标识(称为 IRQ 线),不同的设备对应不同的中断。 在处理器执行到由于编程失误而导致的错误指令的时候,或者是在执行期间出现特殊情况(如缺页),必须靠内核来处理的时候,处理器就会产生一个异常。 中断处理程序 中断发生时,内核会执行的一个函数,称为中断处理程序/中断服务例程。 因为中断可能随时发生,即中断处理程序可能随时执行,所以必须确保中断处理程序能够快速执行,以尽快恢复被中断的代码的执行。 为了满足上述目标,一般把中断处理划分为上下两部。 中断处理程序是上半部,它接收到一个中断后,就立即开始执行,但只做有严格时限的工作。这些工作都是在所有中断被禁止的情况下完成的。 允许稍后完成的工作会推迟到下半部,在以后的某个合适的时机,下半部会被执行。 中断处理程序无需是可重入的。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽掉,以防止在同一中断线上接收另一个新的中断。而其他的中断都是打开的,所以这些不同中断线上的其他中断都能被处理,但当前中断线总是被禁止的。 中断上下文 当执行一个中断处理程序时,内核处于中断上下文中。 中断上下文没有后备进程,所以中断上下文不可以睡眠(如果可以睡眠,那怎么再对它进行重新调度以使其再次运行呢?) 来源: CSDN

linux系统管理-进程管理

拈花ヽ惹草 提交于 2019-12-21 00:15:14
目录 linux系统管理-进程管理 程序和进程的区别 进程的生命周期 进程状态管理命令(静态) 进程的相关命令 动态进程监控(top) 中断:硬中断 软中断: top命令的使用 信号管理进程(kill) linux系统管理-进程管理 程序和进程的区别 1.程序是数据和指令的集合,是一个静态的概念,比如/bin/ls、/bin/cp等二进制文件,同时程序可以长期存在系统中。 2.进程是一个程序的运行过程,是一个动态概念,进程是存在生命周期概念的,也就是说进程会随着程序的终止而销毁,不会永远在系统中存在。 进程的生命周期 程序运行是进程的状态关系 1.当父进程接收到任务调度时,会通过fork派生子进程来处理,那么子进程会集成父进程的衣钵。 2.子进程在处理任务代码时,父进程会进入等待的状态... 3.如果子进程在处理任务过程中,父进程退出了,子进程没有退出,那么这些子进程就没有父进程来管理了,就变成了僵尸进程。 4.每个进程都会有自己的PID号,(process id)子进程则PPID 进程状态管理命令(静态) 使用ps命令查看当前的进程状态(静态查看) 常用组合:ps aux 查看进程 [root@zls ~]# ps aux a:显示所有与终端相关的进程,由终端发起的 u:显示用户导向的用户列表 x:显示所有与终端无关的进程 在多任务处理操作系统中,每个CPU(或核心

java数据结构类--笔记

谁都会走 提交于 2019-12-20 04:12:32
程序的灵魂是算法。提到算法,肯定离不开数据结构。今天就聊一聊java中的和数据结构相关的类。 java.util包 concurrent包 里面是和并发编程相关的类 主要是:原子类–锁--并发的数据结构类【队列,链表,哈希…】 atomic—原子类【 https://blog.csdn.net/boom_man/article/details/78352722 】 locks—锁 Lock锁和同步块的区别 1.同步块只能包含在一个方法内----而lock()和unlock()操作却可以在跨越多个不同的方法使用。 2.同步块不支持公平性,任一个线程都能获取已经被释放的锁,不能指定优先权。但我们却可以使用Lock API指定公平属性从而实现公平性。它能确保等待时间最长的线程优先获取锁。 3.当一个线程不能访问同步块时,它会被阻塞住。而 Lock API提供的有 tryLock()方法,使用该方法,只有在锁不被其他线程持有且可用时,才会真正获取锁。这将极大地降低阻塞时间。 4.那些获取访问同步块的等待线程不能被中断,Lock API提供了一个 lockInterruptbly()方法,当线程正在等待锁时,该方法可以用于中断该线程。’ 接口 ReadWriteLock读写锁 ReadWriteLock维护一对关联锁,一个用于只读操作,一个用于写入。只要没有写入程序

多线程: 多线程中断机制

时光毁灭记忆、已成空白 提交于 2019-12-19 12:41:37
在 java中启动线程非常容易,大多数情况下是让一个线程执行完自己的任务然后自己停掉。一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果,比如会带着自己所持有的锁而永远的休眠,迟迟不归还锁等。在当前的api中,Thread.suspend、Thread.stop等方法都被Deprecated了,线程只能用interrupt中断,而且不是立刻中断,只是发了一个类似于信号量的东西,通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了,至于什么时候中断,这个有系统判断,会在一个合适的时候进行中断处理。 /** * Created by Zero on 2017/8/17. */ public class ThreadTest1 { public static void main(String[] args) { NThread nThread = new NThread(); System.out.println("interrupt执行前"); nThread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } nThread.interrupt(); System.out.println(

Java并发系列[10]----ThreadPoolExecutor源码分析

冷暖自知 提交于 2019-12-19 01:16:27
在日常的开发调试中,我们经常会直接new一个Thread对象来执行某个任务。这种方式在任务数较少的情况下比较简单实用,但是在并发量较大的场景中却有着致命的缺陷。例如在访问量巨大的网站中,如果每个请求都开启一个线程来处理的话,即使是再强大的服务器也支撑不住。一台电脑的CPU资源是有限的,在CPU较为空闲的情况下,新增线程可以提高CPU的利用率,达到提升性能的效果。但是在CPU满载运行的情况下,再继续增加线程不仅不能提升性能,反而因为线程的竞争加大而导致性能下降,甚至导致服务器宕机。因此,在这种情况下我们可以利用线程池来使线程数保持在合理的范围内,使得CPU资源被充分的利用,且避免因过载而导致宕机的危险。在Executors中为我们提供了多种静态工厂方法来创建各种特性的线程池,其中大多数是返回ThreadPoolExecutor对象。因此本篇我们从ThreadPoolExecutor类着手,深入探究线程池的实现机制。 1. 线程池状态和线程数的表示 1 //高3位表示线程池状态, 后29位表示线程个数 2 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 3 private static final int COUNT_BITS = Integer.SIZE - 3; 4 private

系统调用

痞子三分冷 提交于 2019-12-18 22:57:29
由前2篇文章做基础,现在可以理解系统调用了。 用户空间栈&系统空间栈 中断&异常 系统调用定义 系统调用是内核提供的一系列强大的函数。它们在内核中实现,然后通过一定的方式(X86是软中断,也即门陷入)呈现给用户,是用户程序与内核交互的接口。 注意,我们在程序中用调用read、write函数时,这些不是系统调用函数,而是glibc库包装后,进行一些处理,然后再调用系统调用。如果想在程序中直接调用 的 话,需要调用_syscall()函数。 上下文(context) 上下文简单说来就是一个环境,相对于进程而言,就是进程执行时的环境。具体来说就是各个变量和数据,包括所有的寄存器变量、进程打开的文件、内存信息等。 一个进程的上下文可以分为三个部分:用户级上下文、寄存器上下文以及系统级上下文。 用户级上下文: 正文、数据、用户堆栈以及共享存储区; 寄存器上下文: 通用寄存器、程序寄存器(IP)、处理器状态寄存器(EFLAGS)、栈指针(ESP); 系统级上下文: 进程控制块task_struct、内存管理信息(mm_struct、vm_area_struct、pgd、pte)、内核栈。 当发生进程调度时,进行进程切换就是上下文切换(context switch).操作系统必须对上面提到的全部信息进行切换,新调度的进程才能运行。而系统调用进行的模式 切换(mode switch)