精华内容
下载资源
问答
  • Java:线程:CPU核心数目 与 多线程

    千次阅读 2018-10-01 00:16:29
     就绪:调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。 ...

    1.多线程的几个状态?以及何时处于这个状态?

           开始(创建):在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。

      就绪:当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。

      运行:线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。

      阻塞: 线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。

      结束:如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

    2.时间片的概念是什么?


    时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。而不会造成CPU资源浪费。在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。但在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。 

    ================================================================================

     

    一直以来有这样的疑惑,在现如今多核多线程的电脑处理器之下,一个进程中的几个线程是 怎么运行的呢?(是经系统和JVM分配少量的资源 最后轮流切换 时间调度?还是这几个线程分配到不同的核上同时运行?)
    今天就这一问题查了一些资料,现整理如下:

    单个CPU一个时刻只能运行一个线程?

    单核CPU电脑同一时间内只能执行一个线程,首先了解一下,CPU执行的过程 ,它是把时间分成若干个小时间段,这些时间段很小的,系统中有很多进程,每个进程中又包含很多线程,在同一 时间段 内,电脑CPU只能处理一个线程(线程A),而下一个 时间段 就不一定是上一个时间段内执行的那个线程(线程A)了,可能是别的线程(线程B 吧)

    CPU采用的是类似于时间片轮转的机制,也就是说同一时间一条进程提出执行请求时,其他进程只能等待它执行完毕,CPU才会处理其他请求。其他进程相当于在排队等待中。当然了,为了避免某条进程无限制时间的执行,一般会限定一个时间,超时 的话,CPU根据一定的线程调度算法来切换线程。可以看做很多线程在并发执行。其实还是在某一个时间点上只有一个线程在运行罢了。
    多核的话,每个核心都是同样的原理。但是两个核心就可以通过系统分配资源,同时执行不同的进程,这个就更复杂了。
    每条进程都有CPU分配的进程号的。避免混乱。

    一个核心就是实实在在的一个cpu处理设备 线程的概念可以理解成电脑处理信息的通道 既一个线程一个通道 一般来说一个cpu核心处理一个通道的信息 但也不是绝对 因特尔支持超线程技术的cpu每个核心可以处理两个或多个通道的信息 这就可以形容为超线程(既多出来的通道的处理能力)但前提是软件也必须的支持超线程才行 否则单核双线程或多线程也只能有单个通道工作 从某种意义上来说cpu的能力被浪费了 所以网友一般就会说 真正的核心数(通道) 比虚拟出来的核心(通道)来个更实在。最后 线程数决定这CPU能同时处理几件事情,在没有超线程技术的情况下核心数等於线程数。

    java线程调度

    CPU对于各个线程的调度是随机的(分时调度),在Java程序中,JVM负责线程的调度。 线程调度是指按照特定的机制为多个线程分配CPU的使用权,也就是实际执行的时候是线程,因此CPU调度的最小单位是线程,而资源分配的最小单位是进程。

    JVM调度的模式有两种:分时调度抢占式调度。

    分时调度 是所有线程轮流获得CPU使用权,并平均分配每个线程占用CPU的时间;

    抢占式调度 是根据线程的优先级别来获取CPU的使用权。JVM的线程调度模式采用了抢占式模式。既然是抢占调度,那么我们就能通过设置优先级来“有限”的控制线程的运行顺序,注意“有限”一次。

    CPU核数 跟多线程 的关系

      要说多线程就离不开进程,进程和线程的区别在这里就不详细说了,只将关键的几点:

    a)进程之间是 相互独立的,不共享 内存和数据,线程之间 的内存和数据是 公用的,每个线程只有自己的一组CPU指令、寄存器和堆栈,对于线程来说只有CPU里的东西是自己独享的,程序中的其他东西都是跟同一个进程里的其他线程共享的。

    b)操作系统创建进程时要分配好多外部资源,所以开销大。(这个跟操作系统有关,有人做过实验,window创建进程的开销大,Linux创建进程的开销就很小。)

    再来说一下CPU,过去单CPU时代最先是单任务阶段 在一个时间点 只能执行单一程序。之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程。虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行。而现在多核CPU的情况下,同一时间点可以执行多个任务(并行),具体到这个任务在CPU哪个核上运行,这个就跟操作系统和CPU本身的设计相关了。

    我们假设一个极端的情况:在一台单核计算机上只运行2个程序,一个是我们的程序A,另一个是操作系统的程序B,每个程序是一个进程。单核CPU的时候,A和B在CPU上交替运行,具体的分配方式由操作系统来判断,我这里猜测应该跟A和B的线程数有关,因为线程是CPU级别的,如果A有5个线程,B也有5个线程,那么CPU分配给A和B的时间应该是1:1的;如果A增加到15个线程,CPU分配给A和B的时间应该是3:1的比例。所以此时如果A的线程数多,那么获得的CPU执行次数就多,处理的速度也就快了。以上假设的前提是:①A和B的优先级相同,②A和B都是只消耗CPU资源的程序。

    如果相同的情况用一个双核的计算机来处理又会是什么结果呢?假设这个双核的计算机和操作系统比较傻,把A进程分配到核1上,B进程分配到核2上,那不管A有几个线程,都是用核1来处理,那么时间肯定是一样的。不过现实中应该不会有这么傻的CPU和操作系统吧。所以赶紧还是会根据线程来进行处理,当A的线程比B多时,会占用核2来处理A的线程。

    刚才说的是只消耗CPU资源的程序,但这样的程序在实际应用中基本上是没有的,总会有跟资源打交道的。比如读个文件,查个数据库,访问一个网络连接等等。这个时候多线程才真正体现出优势,在一个进程中,线程a去读文件,线程b去查数据库,线程c去访问网络,a先用一下CPU,然后去读文件,此时CPU空闲,b就用一下,然后去查数据库,……,相对于读文件、查数据库、访问网络来说CPU计算的时间几乎可以忽略不计,所以多线程实际上是计算机多种资源的并行运用,跟CPU有几个核心是没什么关系的。

     

    https://my.oschina.net/xiaotian120/blog/196201 (java线程调度)
    http://blog.csdn.net/ziwen00/article/details/38097297(这篇写的也不错)

    原文参考:https://blog.csdn.net/qq_33530388/article/details/62448212

    展开全文
  • 有多个线程在操作时,如果系统只有一个CPU(单核心),则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程...

    并发与并行区别

    并发:当有多个线程在操作时,如果系统只有一个CPU(单核心),则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

    并行:当系统有一个以上CPU(一个CPU具备多核心)时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

    区别:并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行。

    实际的数据统计范例

    某公司有4个工厂,分布在不同地区,同一时段都生产了P1,P2,P3这3种产品,产量(单位;吨),

    工厂\产品 P1 P2 P3
    5 2 4
    3 8 2
    6 0 4
    0 1 6

    可用下面的矩阵描述

    ,其中4行分别表示甲乙丙丁4个工厂的生产情况,3列分布表示3种产品P1,P2,P3的产量。

    产品P1的单件利润为2(单位:元)占用存储空间为4(单位:立方米),

    产品P2的单件利润为1(单位:元)占用存储空间为3单位:立方米),

    产品P3的单件利润为3(单位:元)占用存储空间为4单位:立方米),

    试用矩阵的计算方式来统计这些数据。

    产品 单件利润/单件体积
    P1 2/4
    P2 1/3
    P3 3/2

    可用下面的矩阵描述

    ,其中第1列表示3种产品的单件利润,第2列表示3种产品的单件体积。

    矩阵C的第1列数据分别表示4个工厂的利润,第2列分别表示4个工厂产品需要的存储空间。

    我们将使用Java代码来实现数据的统计

    定义存储矩阵数据的对象:

    package com.contoso;
    
    public class Matrix {
    
        private final int[][] matrix;
    
        public Matrix(int rows, int cols) {
            matrix = new int[rows][cols];
        }
    
        public int getCols() {
            return matrix[0].length;
        }
    
        public int getRows() {
            return matrix.length;
        }
    
        public int getCellValue(int row, int col) {
            return matrix[row][col];
        }
    
        public void setCellValue(int row, int col, int value) {
            matrix[row][col] = value;
        }
    }

    接下来我们将使用两种不同的实现方式来统计数据:

    第1种方式:单线程统计方式

    package com.contoso;
    
    /**
     * 单线程矩阵乘法
     * 
     */
    public class MatrixMultiply {
    
        public static void main(String[] args) {
            /*
            A矩阵:4行3列
            5 2 4 
            3 8 2 
            6 0 4 
            0 1 6 
             */
            long start = System.nanoTime();
            Matrix a = new Matrix(4, 3);
            a.setCellValue(0, 0, 5);
            a.setCellValue(0, 1, 2);
            a.setCellValue(0, 2, 4);
            a.setCellValue(1, 0, 3);
            a.setCellValue(1, 1, 8);
            a.setCellValue(1, 2, 2);
            a.setCellValue(2, 0, 6);
            a.setCellValue(2, 1, 0);
            a.setCellValue(2, 2, 4);
            a.setCellValue(3, 0, 0);
            a.setCellValue(3, 1, 1);
            a.setCellValue(3, 2, 6);
            print(a);
            /*
            B矩阵:3行2列
            2 4 
            1 3 
            3 2 
             */
            Matrix b = new Matrix(3, 2);
            b.setCellValue(0, 0, 2);
            b.setCellValue(1, 0, 1);
            b.setCellValue(2, 0, 3);
            b.setCellValue(0, 1, 4);
            b.setCellValue(1, 1, 3);
            b.setCellValue(2, 1, 2);
            print(b);
            /*
            C矩阵:4行2列  C = A * B
            */
            print(multiply(a, b));
            long end = System.nanoTime();
            double timeTaken = (end - start) / 1e9;
            System.out.println("Matrix Multiply Time Taken in seconds:" + timeTaken);
        }
    
        public static void print(Matrix mat) {
            for (int i = 0; i < mat.getRows(); i++) {
                for (int j = 0; j < mat.getCols(); j++) {
                    System.out.printf("%d ", mat.getCellValue(i, j));
                }
                System.out.println();
            }
            System.out.println();
        }
    
        public static Matrix multiply(Matrix a, Matrix b) {
            if (a.getCols() != b.getRows()) {
                throw new IllegalArgumentException("rows/columns mismatch");
            }
            Matrix result = new Matrix(a.getRows(), b.getCols());
            for (int i = 0; i < a.getRows(); i++) {
                for (int j = 0; j < b.getCols(); j++) {
                    for (int k = 0; k < a.getCols(); k++) {
                        result.setCellValue(i, j, result.getCellValue(i, j) + a.getCellValue(i, k) * b.getCellValue(k, j));
                    }
                }
            }
            return result;
        }
    }

    请注意以下单线程统计需要的时间:

    run:
    5 2 4 
    3 8 2 
    6 0 4 
    0 1 6 
    
    2 4 
    1 3 
    3 2 
    
    24 34 
    20 40 
    24 32 
    19 15 
    
    Matrix Multiply Time Taken in seconds:0.036336188
    BUILD SUCCESSFUL (total time: 0 seconds)

    第2中方式:超快并行执行的多核心CPU矩阵乘法在数据统计方面的应用

    package com.contoso;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ForkJoinPool;
    import java.util.concurrent.RecursiveAction;
    
    /**
     * 超快并行执行的多核心CPU矩阵乘法在数据统计方面的应用
     *
     */
    public class RecursiveMatrixMultiply extends RecursiveAction {
    
        private final Matrix a, b, c;
        private final int row;
    
        public RecursiveMatrixMultiply(Matrix a, Matrix b, Matrix c) {
            this(a, b, c, -1);
        }
    
        public RecursiveMatrixMultiply(Matrix a, Matrix b, Matrix c, int row) {
            if (a.getCols() != b.getRows()) {
                throw new IllegalArgumentException("rows/columns mismatch");
            }
            this.a = a;
            this.b = b;
            this.c = c;
            this.row = row;
        }
    
        @Override
        public void compute() {
            if (row == -1) {
                List<RecursiveMatrixMultiply> tasks = new ArrayList<>();
                for (int row = 0; row < a.getRows(); row++) {
                    tasks.add(new RecursiveMatrixMultiply(a, b, c, row));
                }
                invokeAll(tasks);
            } else {
                multiplyRowByColumn(a, b, c, row);
            }
        }
    
        public static void multiplyRowByColumn(Matrix a, Matrix b, Matrix c, int row) {
            for (int j = 0; j < b.getCols(); j++) {
                for (int k = 0; k < a.getCols(); k++) {
                    c.setCellValue(row, j, c.getCellValue(row, j) + a.getCellValue(row, k) * b.getCellValue(k, j));
                }
            }
        }
    
        public static void print(Matrix mat) {
            for (int i = 0; i < mat.getRows(); i++) {
                for (int j = 0; j < mat.getCols(); j++) {
                    System.out.print(mat.getCellValue(i, j) + " ");
                }
                System.out.println();
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            long start = System.nanoTime();
            /*
            A矩阵:4行3列
            5 2 4 
            3 8 2 
            6 0 4 
            0 1 6 
             */
            Matrix a = new Matrix(4, 3);
            a.setCellValue(0, 0, 5);
            a.setCellValue(0, 1, 2);
            a.setCellValue(0, 2, 4);
            a.setCellValue(1, 0, 3);
            a.setCellValue(1, 1, 8);
            a.setCellValue(1, 2, 2);
            a.setCellValue(2, 0, 6);
            a.setCellValue(2, 1, 0);
            a.setCellValue(2, 2, 4);
            a.setCellValue(3, 0, 0);
            a.setCellValue(3, 1, 1);
            a.setCellValue(3, 2, 6);
            print(a);
    
            /*
            B矩阵:3行2列
            2 4 
            1 3 
            3 2 
             */
            Matrix b = new Matrix(3, 2);
            b.setCellValue(0, 0, 2);
            b.setCellValue(1, 0, 1);
            b.setCellValue(2, 0, 3);
            b.setCellValue(0, 1, 4);
            b.setCellValue(1, 1, 3);
            b.setCellValue(2, 1, 2);
            print(b);
    
            /*
            C矩阵:4行2列  C = A * B
             */
            Matrix c = new Matrix(4, 2);
            ForkJoinPool pool = new ForkJoinPool();
            pool.invoke(new RecursiveMatrixMultiply(a, b, c));
            print(c);
            long end = System.nanoTime();
            double timeTaken = (end - start) / 1e9;
            System.out.println("Recursive Matrix Multiply Time Taken in seconds:" + timeTaken);
            System.err.println("单颗CPU内核数 = " + Runtime.getRuntime().availableProcessors());
        }
    }

    请注意并行计算的多核心CPU矩阵乘法统计需要的时间:

    run:
    5 2 4 
    3 8 2 
    6 0 4 
    0 1 6 
    
    2 4 
    1 3 
    3 2 
    
    24 34 
    20 40 
    24 32 
    19 15 
    
    单颗CPU内核数 = 4
    Recursive Matrix Multiply Time Taken in seconds:0.003261084
    BUILD SUCCESSFUL (total time: 0 seconds)

    结论:多核心CPU并行矩阵乘法计算要比单线程矩阵乘法计算快11倍。

    展开全文
  • 运行机制 指令就是处理器(CPU)能识别、执行的最基本命令 指令分为特权指令和非特权指令 特权指令(如:内容清零指令),是不允许用户程序使用的 非特权指令(如:普通的...当CPU处于核心态时,CPU可以执行特权指令、非

    运行机制

    • 指令就是处理器(CPU)能识别、执行的最基本命令
      • 指令分为特权指令和非特权指令
        • 特权指令(如:内容清零指令),是不允许用户程序使用的
        • 非特权指令(如:普通的运势指令)
    • CPU通过两种处理器状态来判断当前是否可以执行特权指令。
      • 两种处理器状态分为用户态(目态)和核心态。
        • 两种处理器状态是用程序状态字寄存器(PSW)中的某标志位来标识当前处理器处于什么状态。(如:0为用户态,1为核心态)
        • 当CPU处于用户态时,CPU只能执行非特权指令
        • 当CPU处于核心态时,CPU可以执行特权指令、非特权指令
    • 计算机系统将程序分为两种程序
      • 两种程序分为内核程序和应用程序。
        • 操作系统的内核程序是系统的管理者,既可以执行特权指令,也可以执行非特权指令,运行在核心态
        • 为了保证系统能安全运行,普通应用程序只能执行非特权指令,运行在用户态
      • 内核是计算机上配置的底层软件,是操作系统最基本、最核心的部分
      • 内核有时钟管理、中断处理、原语、对系统资源进行管理的功能四部分组成(时钟管理、中断处理和原语是与硬件关联较紧密的模块)
        • 时钟管理:实现计时功能
        • 中端处理:负责实现中断机制
        • 原语:
          1. 是一种特殊的程序
          2. 处于操作系统最底层,是最接近硬件的部分
          3. 这种程序的运行具有原子性——其运行只能一气呵成,不能中断
          4. 运行时间较短,调用频繁
        • 对系统资源进行管理的功能(有的操作系统不把这部分功能归为“内核功能”,不同的操作系统对内核功能的划分并不一样)
          1. 进程管理
          2. 存储器管理
          3. 设备管理

    体系结构

    • 大内核:
      • 将操作系统的主要功能模块都作为系统内核,运行在核心态
      • 优点:高性能
      • 缺点:内核代码庞大,结构混乱,难以维护
    • 微内核:
      • 只把最基本的功能保留在内核
      • 优点:内核功能少,结构清晰,方便维护
      • 缺点:需要频繁地在核心态和用户态之间切换,性能低### 运行机制
    • 指令就是处理器(CPU)能识别、执行的最基本命令
      • 指令分为特权指令和非特权指令
        • 特权指令(如:内容清零指令),是不允许用户程序使用的
        • 非特权指令(如:普通的运势指令)
    • CPU通过两种处理器状态来判断当前是否可以执行特权指令。
      • 两种处理器状态分为用户态(目态)和核心态。
        • 两种处理器状态是用程序状态字寄存器(PSW)中的某标志位来标识当前处理器处于什么状态。(如:0为用户态,1为核心态)
        • 当CPU处于用户态时,CPU只能执行非特权指令
        • 当CPU处于核心态时,CPU可以执行特权指令、非特权指令
    • 计算机系统将程序分为两种程序
      • 两种程序分为内核程序和应用程序。
        • 操作系统的内核程序是系统的管理者,既可以执行特权指令,也可以执行非特权指令,运行在核心态
        • 为了保证系统能安全运行,普通应用程序只能执行非特权指令,运行在用户态
      • 内核是计算机上配置的底层软件,是操作系统最基本、最核心的部分
      • 内核有时钟管理、中断处理、原语、对系统资源进行管理的功能四部分组成(时钟管理、中断处理和原语是与硬件关联较紧密的模块)
        • 时钟管理:实现计时功能
        • 中端处理:负责实现中断机制
        • 原语:
          1. 是一种特殊的程序
          2. 处于操作系统最底层,是最接近硬件的部分
          3. 这种程序的运行具有原子性——其运行只能一气呵成,不能中断
          4. 运行时间较短,调用频繁
        • 对系统资源进行管理的功能(有的操作系统不把这部分功能归为“内核功能”,不同的操作系统对内核功能的划分并不一样)
          1. 进程管理
          2. 存储器管理
          3. 设备管理

    体系结构

    • 大内核:
      • 将操作系统的主要功能模块都作为系统内核,运行在核心态
      • 优点:高性能
      • 缺点:内核代码庞大,结构混乱,难以维护
    • 微内核:
      • 只把最基本的功能保留在内核
      • 优点:内核功能少,结构清晰,方便维护
      • 缺点:需要频繁地在核心态和用户态之间切换,性能低

    思维导图

    操作系统的运行机制、体系结构思维导图

    展开全文
  • 1.3 操作系统的运行环境 知识图谱 一、操作系统的运行机制 计算机系统中,通常 CPU 执行两种不同性质的程序:... CPU 处于核心态时,CPU 既可以执行特权指令也可以执行非特权指令。用户自编程序运行在用户态,操作系

    1.3 操作系统的运行环境

    知识图谱

    操作系统的运行环境

    一、操作系统的运行机制

    计算机系统中,通常 CPU 执行两种不同性质的程序:

    • 操作系统内核程序:通常会执行一些特权指令(指计算机中不允许用户直接执行的指令,如中断指令,这些指令必须由操作系统调度执行),
    • 用户自编程序:主要执行非特权指令

    在具体实现上,将 CPU 状态划分为用户态(目态)和核心态(管态、内核态)。当 CPU 处于用户态时,只能执行非特权指令;当 CPU 处于核心态时,CPU 既可以执行特权指令也可以执行非特权指令用户自编程序运行在用户态,操作系统内核程序运行在核心态

    现代操作系统几乎都是层次式的结构:

    • 与硬件关联较高的模块,如时钟关联、中断处理,处于最低层;
    • 运行频率高的程序,如进程关联、存储器管理,位于上一层。

    这两部分构成了操作系统的内核,都运行在核心态。

    大多数操作系统内核包含以下方面:

    1. 时钟管理

    在操作系统中时钟的功能主要有两大类:

    • 向用户提供系统时间;
    • 通过时钟中断的管理,实现进程的切换。

    2. 中断机制

    引入中断技术的最初目的是提高多道环境中 CPU 的利用率。

    后来随着现代操作系统的发展,中断成为了操作系统各项操作的基础,如鼠标键盘信息的输入、进程的管理与调度、文件访问等。可以说现代操作系统是依靠中断驱动的软件。

    中断机制中,只由小部分是属于内核,它们负责保护和恢复中断现场的信息,转移控制权到相关的处理程序。这样可以减少中断处理时间,提高 CPU 利用率。

    3. 原语

    按层次结构设计的操作系统,底层必然是一些可以被调用的公用小程序,它们各自完成一个规定的操作。它们拥有如下特点:

    • 处于操作系统底层,是最接近硬件的部分;
    • 程序运行具有原子性;
    • 程序运行时间短,调用频繁。

    通常把具有这些特点的程序称为原语(Atomic Operation)。定义原语的直接方法是关闭中断,让所有动作都不可分割的完成后再打开中断。

    4. 系统控制的数据结构及处理

    系统中用来登记状态信息的数据结构有很多,为了实现有效的管理,系统需要一些基本的操作。常见操作有以下几个:

    • 进程管理:进程状态管理、进程调度和分派、创建与撤销进程控制块等;
    • 存储器管理:存储器的空间分配和回收、内存信息保护程序、代码对换程序等;
    • 设备管理:缓冲区管理、设备分配和回收等。

    从上述内容可以发现,核心态指令实际上包括系统调用类指令和一些针对时钟、中断和原语的操作指令。

    二、中断和异常的概念

    为了实现 CPU 用户态和核心态的切换,在 CPU 核心态建立了通道, 以便实现从用户态进入核心态。在实际操作系统中,CPU 运行上层程序时唯一能进入这些通道的途径就是通过中断和异常

    中断(Interruption)也称外中断,指来自 CPU 指令以外的事情发生。例如 I/O 设备结束中断表示设备输入/输出完成,希望处理机能够向设备发下一个输入/输出请求,同时让程序继续运行。

    时钟中断,表示一个固定的时间片已到,让处理机处理计时、启动定时任务等。这一类中断通常与当前程序运行无关的事情。

    异常(Exception)也称内中断、例外和陷入(trap),指源自 CPU 执行指令内部的事件,如地址越界、算术溢出、虚存系统的缺页及专门的陷入指令等引起的事件。关于异常的处理一般要依赖于当前程序的运行现场,而且异常通常不能被屏蔽,一旦出现必须立即处理

    三、系统调用

    所谓系统调用,是指用户在程序中调用操作系统所提供的一些子功能,系统调用可视为特殊的公告子程序。

    这些系统调用按功能大致可以分为如下几类:

    • 设备管理:完成设备的请求或释放,以及设备启动等功能;
    • 文件管理:完成文件的读、写、创建以及删除等功能;
    • 进程管理:完成进程的创建、撤销、阻塞及唤醒等功能;
    • 进程通信:完成进程之间的消息传递或信号传递等功能;
    • 内存管理:完成内存的分配、回收以及获取作业占用内存区大小及初始地址等功能。

    用户程序不能直接执行对系统影响飞车大的操作,必须通过系统调用的方式请求操作系统代为执行,以便提高系统的稳定性和安全性,防止用户程序随意更改或访问重要的系统资源,影响其它进程的执行。

    系统调用执行过程

    在操作系统层面上我们关心的是系统核心态和用户态的软件实现与切换。

    列举一些由用户态转向核心态的例子:

    • 用户程序要求操作系统的服务,即系统调用;
    • 发生了一次中断;
    • 用户程序中产生了一个错误状态;
    • 用户程序试图执行一条特权指令;
    • 从核心态转为用户态也是由特权指令产生,一般是中断返回指令。

    由用户态转为核心态,不仅仅要切换状态,所用的堆栈也可能需要由用户堆栈切换为系统堆栈,但是系统堆栈也是属于该进程的。

    如程序运行由用户态转为核心态,就会用到访管指令,访管指令是在用户态使用的,因此它是非特权指令。

    参考资料:王道考研——操作系统

    展开全文
  • **当CPU处于核心态时,特权指令、非特权指令都可以执行 特权指令:如内存清零指令;非特权指令:如普通的加减乘除运算指令 用程序状态字寄存器(PSW)的某个标志位来标识当前处理器所处的状态,比如0为用户态,1为核...
  • 如果线程数不多于CPU核心数,会把各个线程都分配一个核心,不需分片,而线程数多于CPU核心数时才会分片。 2、并发和并行的区别 并发:有多个线程在操作时,如果系统只有一个CPU,把CPU运行时间划分成若干个时间...
  • 所以从一开始:计算机启动时,引导线程(通常是处理器0中核心0中的线程0)开始从地址0xfffffff0中获取代码。所有其余的CPU /内核都处于特殊的睡眠状态,称为Wait-for-SIPI(WFS)。然后在加载OS之后,它开始管理进程并...
  • 【JAVA核心知识】6.1: JAVA IO基础

    千次阅读 热门讨论 2020-11-24 11:41:02
    阻塞IO在数据未准备就绪时用户线程处于阻塞状态:用户线程发起IO请求时,内核会查看数据是否准备就绪,如果未准备就绪就会等待数据准备就绪,在这个期间线程处于阻塞状态,用户线程交出CPU,在数据准备就绪后,内核...
  • 一个可运行的进程不一定会使用CPU,但是Linux调度器决定下一个要运行的进程时,它会从可运行的进程队列种挑选。如果进程是可运行的,同时又在等待使用处理器,这些进程就构成了运行队列。运行的队列越长,处于等待...
  • 背景由于在多处理器环境中某些资源的有限性,有时需要互斥访问(mutual exclusion),这时候就需要引入锁的概念,只有获取了锁的任务才能够对资源进行访问,由于多线程的核心CPU的时间分片,所以同一时刻只能有一个...
  • 这种切换时非常耗时的,一个空的系统大概会占用200个CPU周期,但是造成内核对象比用户模式下的同步机制慢几个数量级的原因,是伴随调度新线程而来的刷新高速缓存以及错过高速缓存。  进程内核对象在创建的...
  • 背景由于在多处理器环境中某些资源的有限性,有时需要互斥访问(mutual exclusion),这时候就需要引入锁的概念,只有获取了锁的任务才能够对资源进行访问,由于多线程的核心CPU的时间分片,所以同一时刻只能有一个...
  • <p>PS: stdin 默认是处于pause状态的,要想读取数据首先要将其 resume() 可读流还有一个 同步</strong> 的 read() 方法,流读取完后会返回 chunk或null ,课这样来用: <pre><code> var ...
  • CPU上运行,那么其他的CPU核心处于空闲状态,浪费了系统资源;引入多线程可以解决这个问题,可以充分利用系统CPU 的资源; 例如可以:线程2在CPU核心0上运行、线程2在CPU核心2上运行。 又或者,应用程序需要...
  • 一、基础概念多CPU:一台计算机上多个物理CPU多核:一个CPU上多个核心超线程技术:一个核心多个执行执行单元二、CPU内存...那么总线锁的意思是当CPU1拿到变量处理完的时候CPU2处于阻塞状态,当CPU1处理完之后,CPU2...
  • 一、基础概念多CPU:一台计算机上多个物理CPU多核:一个CPU上多个核心超线程技术:一个核心多个执行执行单元二、CPU内存...那么总线锁的意思是当CPU1拿到变量处理完的时候CPU2处于阻塞状态,当CPU1处理完之后,CPU2...
  • 用户态和核心态

    2019-07-27 19:42:05
    一个进程运行于核心态的时候,CPU处于核心态,一个进程运行于用户态的时候,CPU处于用户态。 X86型的CPU拥有四种级别,RING 0 级别最高,为核心态,RING 3级别最低,为用户态。 简而言之: 用户态就是指...
  • 多线程系列问题汇总

    2019-07-02 07:57:00
    什么是上下文切换? 多线程编程中,一般线程的个数都大于 CPU核心个数,而一个 ...线程的时间片用完时,CPU 就会重新处于就绪状态,并让其他线程使用,这整个过程就属于一次上下文切换。 当前任务在执行完 CPU...
  • cpu处于满负载的情况时,我们需要监控cpu使用率可查看DB日志、web服务器日志、系统日志(top、free、uptime、sar)查看cpu的闲置率。一般情况会制定一个cpu阀值可用cpu不小于20%,若小于20则告警。 2、内存 内存的...
  • 多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。一个线程的时间片用完的...
  • 作业4

    2020-11-05 12:03:40
    进程在唤醒前,CPU处于空闲状态时,某进程被唤醒后,系统会使它立即投入运行,但这不是剥夺调度方式。仅它被唤醒后,立即抢占当前正在运行进程的CPU才可说系统采用的是剥夺式调度方式。 ...
  • 什么是上下文切换?

    2020-03-31 11:15:23
    一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。 概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个...
  • 并发所带来的好处1. 并发在某些情况(并不是所有情况)下可以带来性能上的提升1) 提升对CPU的使用效率 提升多核... 提升访问I/O时CPU的利用率:一个线程要在网上下载一些东西的时候,这个线程将处于阻塞状态...
  • 现在都是采用的多核CPU,尽可能的提升并发性能,但是有一个问题是程序的本身并发处理能力不强,就会造成不能够合理的利用多核心资源,例如,多个线程运行时,一个CPU分配的任务较少,CPU完成其任务后,处于空闲...
  • 为了充分利用多CPU、多核CPU的性能优势,级软基软件系统应该可以充分“挖掘”每个CPU的计算能力,决不能让某个CPU处于“空闲”状态。为此,可以考虑把一个任务拆分成多个“小任务”,把多个"小任务"放到多个处理器...
  • 多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。一个线程的时间片用完的...
  • 线程上下文切换

    2021-03-31 14:20:33
    一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程属于一次上下文切换。 换句话说,当前任务在执行完CPU时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换会这个任务时,...

空空如也

空空如也

1 2 3 4 5 6
收藏数 109
精华内容 43
关键字:

当cpu处于核心