精华内容
下载资源
问答
  • 我在这里写了一些多线程的学习总结,在这里写了一些多进程的学习笔记,在这片文章中,就它们并串行执行的情况进行一下对比。 直接上程序 import multiprocessing as mp # 多进程的模块 import threading as td from ...

    原文地址

    学习来源

    分类目录——多进程

    我在这里写了一些多线程的学习总结,在这里写了一些多进程的学习笔记,在这片文章中,就它们并串行执行的情况进行一下对比。

    直接上程序

    import multiprocessing as mp    # 多进程的模块
    import threading as td
    from queue import Queue
    import time
    
    def job(q, n):     # 进程调用测程序,传递的参数为一个queue(队列)对象
        res = 0
        for i in range(n):
            res += i**2
        q.put(res)      # 把结果(就是主进程中函数的返回值)存入队列
    
    # 多进程的执行方案
    def multicore(m, n):
        q = mp.Queue()
        plist = []
        signle_size = int(n/m)      # 分配给每个进程的执行规模
    
        # 把规模n分配给m个进程执行,每个进行执行n/m(即signle_size)
        for e in range(m):
            p = mp.Process(target=job, args=(q, signle_size))
            # 生成进程,并传入要执行的操作(函数),args=参数列表,只传一个参数的时候注意要在参数后面加一个逗号,因为args需要一个可迭代的参量
            p.start()  # 进程操作开始执行
            plist.append(p)
        # .join()必须要和进程创建操作分开
        for pp in plist:
            pp.join()  # 将进程操作设定为关键路径
    
        result = 0
        for e in range(m):
            result += q.get()  # 从结果队列中取值
        print(result)
    
    # 多线程执行方案
    def multithread(m, n):
        q = Queue()
        tlist = []
        signle_size = int(n / m)  # 分配给每个线程的执行规模
    
        # 把规模n分配给m个线程执行,每个进行执行n/m(即signle_size)
        for e in range(m):
            t = td.Thread(target=job, args=(q, signle_size))
            # 生成进程,并传入要执行的操作(函数),args=参数列表,只传一个参数的时候注意要在参数后面加一个逗号,因为args需要一个可迭代的参量
            t.start()  # 进程操作开始执行
            tlist.append(t)
        # .join()必须要和进程创建操作分开
        for tt in tlist:
            tt.join()  # 将进程操作设定为关键路径
    
        result = 0
        for e in range(m):
            result += q.get()  # 从结果队列中取值
        print(result)
    
    # 串行执行方案
    def normol(m, n):
        q = Queue()
        signle_size = int(n / m)  # 分配给每个进程的执行规模
    
        # 把规模n分配给m个步骤执行,每个步骤执行n/m(即signle_size)
        for e in range(m):
            job(q, signle_size)
    
        result = 0
        for e in range(m):
            result += q.get()  # 从结果队列中取值
        print(result)
    
    if __name__ == '__main__':
        n_size = 1000000    # 总规模
        n_mul = 2           # 多线程/进程数,即总规模分配给几个线程/进程执行
    
        # 多进程执行,计算执行时间
        smp = time.time()
        multicore(n_mul, n_size)
        emp = time.time()
        print('time_multicore:',emp-smp)
    
        # 多线程执行,计算执行时间
        smp = time.time()
        multithread(n_mul, n_size)
        emp = time.time()
        print('time_multithread:',emp-smp)
    
        # 串行分步执行,计算执行时间
        smp = time.time()
        normol(n_mul, n_size)
        emp = time.time()
        print('time_normal:',emp-smp)
        
    OutPut1(设置规模n=1000000,分(m=2)个进程/进程/步骤执行)
    83333083333500000
    time_multicore: 0.37401270866394043
    83333083333500000
    time_multithread: 0.3429744243621826
    83333083333500000
    time_normal: 0.3250463008880615
        
    OutPut2(设置规模n=1000000,分(m=10)个进程/进程/步骤执行)
    3333283333500000
    time_multicore: 0.6909716129302979
    3333283333500000
    time_multithread: 0.33600425720214844
    3333283333500000
    time_normal: 0.33300042152404785
        
    OutPut3(设置规模n=10000000,分(m=2)个进程/进程/步骤执行)
    83333308333335000000
    time_multicore: 2.0039618015289307
    83333308333335000000
    time_multithread: 3.3349993228912354
    83333308333335000000
    time_normal: 3.418002128601074
    
    OutPut4(设置规模n=10000000,分(m=10)个进程/进程/步骤执行)
    3333328333335000000
    time_multicore: 1.0810012817382812
    3333328333335000000
    time_multithread: 3.432995557785034
    3333328333335000000
    time_normal: 3.3250246047973633
    

    其中n4=n3=10n2=10n1

    简单说明一下上面的程序,是在总规模n下,分别分m个进程,m个线程,串行分m步执行的对比。

    可以看到,当规模小的时候,使用多线程并没有什么优势,相反生成多进程/线程的操作过程会浪费一定的时间。但是当运算规模变大的时候,多进程会展现出更快的运算速度,并且速度随着进程数的增加而又更大幅度的提升,同样也可以发现,效率的提升并不与进程数的倒数呈严格的线性相关,应该是因为开进程需要时间,临界资源(只允许单点访问)。而多线程在效率上并没有什么提升,反而有所下降,因为多线程是通过分时而实现的伪并行的原因。多线程当然也有其存在的意义,就是“并行”,可以实现多个程序同时运行,并且线程是省资源的,多线程间是共享资源的,不像多进程那样每个进程都需要单独的开销。这么看来这还是多线程的优势,在不多占用资源的前提下,实现了多个程序同时运行,效率上的损失也不是太大。

    展开全文
  • 进程 进程是资源(CPU、内存...线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和...
    1. 进程
      进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行
    2. 线程
      线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

    一个正在运行的软件(如360安全卫士)就是一个进程,一个进程可以同时运行多个任务(病毒查杀,垃圾清理,软件卸载,每个任务就是一个线程), 可以简单的认为进程是线程的集合。

    线程是一条可以执行的路径。多线程就是同时有多条执行路径在同时(并行)执行。

    1. 单核CPU中,顺序编程(串行)
      顺序编程:程序从上往下的同步执行,即如果第一行代码执行没有结束,第二行代码就只能等待第一行执行结束后才能结束。
    public class Main {
        // 顺序编程 吃喝示例:当吃饭吃不完的时候,是不能喝酒的,只能吃完饭才能喝酒
        public static void main(String[] args) throws Exception {
    		// 先吃饭再喝酒
            eat();
            drink();
        }
    
        private static void eat() throws Exception {
            System.out.println("开始吃饭?...\t" + new Date());
            Thread.sleep(5000);
            System.out.println("结束吃饭?...\t" + new Date());
        }
    
        private static void drink() throws Exception {
            System.out.println("开始喝酒?️...\t" + new Date());
            Thread.sleep(5000);
            System.out.println("结束喝酒?...\t" + new Date());
        }
    }
    
    

    总共耗时
    总共耗时10s

    1. 单核CPU中,并发编程
      并发编程:多个任务可以同时做,常用与任务之间比较独立,互不影响。
      单核CPU不停切换线程以达到并行的目的(切换时间非常短,在一个时间段内,近似于线程并行)
    public class Main {
        public static void main(String[] args) {
    	    // 一边吃饭一边喝酒
            new EatThread().start();
            new DrinkThread().start();
        }
    }
    
    class EatThread extends Thread{
        @Override
        public void run() {
            System.out.println("开始吃饭?...\t" + new Date());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结束吃饭?...\t" + new Date());
        }
    }
    
    class DrinkThread extends Thread {
        @Override
        public void run() {
            System.out.println("开始喝酒?️...\t" + new Date());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结束喝酒?...\t" + new Date());
        }
    }
    
    

    在这里插入图片描述
    总共耗时5s

    所以并发能大大提高系统运行速度。

    1. 并行
      多核情况下,多线程分别在不同CPU上运行,从而达到真正的同一时间点,有多个线程。(单核并发在同一个时间点,只能有一个线程)

    2. 上诉案例补充分析

    其实原作者这里并没有说清楚为什么一下子节省了5s,因为按照前面所说的,单核CPU中,多线程是利用CPU的快速线程切换(上下文切换)而达到并发的效果,即(因为是单核,所以只有并发处理的顺序执行)
    在这里插入图片描述
    照理说,总量不变,但是为什么单核系统并发就节约了时间?以及单核系统并发操作一定会节约时间??

    答案是看情况,单核系统的多线程并发不一定节约时间。

    简单说一下,就是在非阻塞的情况下。单核环境下,多线程程序运行速度不快反而慢的多,因为CPU调度多线程上下文切换等消耗影响很严重。

    但是这些是非阻塞的情况下,阻塞的情况下就不是这样了。以下是线程从创建、运行到结束的五个状态:新建状态、就绪状态、运行状态、阻塞状态及死亡状态

    在这里插入图片描述
    从图中看到,分别在执行sleep()和wait()(wait就是手动进行线程挂起)的时候,会造成阻塞情况。其中,sleep会在一定时间后自动改变为ready状态(就绪)后,重新运行;而wait()需要手动进行notify()或者notifyAll()后才会变为ready状态。sleep和wait后,线程都会进入阻塞状态。

    简单了解了阻塞状态后,再返回之前的例子可以发现,这里使用的是sleep对线程进行阻塞。

    于是乎问题又来了,在sleep的时候,又发生了什么?

    sleep的原理,可以参考这篇文章

    学过MCU的都知道一个叫做定时器的玩意,这玩意是和主程序并行的,一个MCU有多个定时器。而sleep就是基于定时器的函数
    所以sleep()在OS中的实现的大概流程如下:

    • 挂起进程(或线程)并修改其运行状态
    • 用sleep()提供的参数来设置一个定时器。
    • 当时间结束,定时器会触发,内核收到中断后修改进程(或线程)的运行状态。例如线程会被标志为就绪而进入就绪队列等待调度

    简单来说就是sleep会给定时器设定一个初始时间,定时器内的时间会递减,当时间为0的时候会给内核一个中断信号,告诉内核线程已经就绪,可以重新运行。

    好了,有了定时器的概念,就很好理解这个例子下并行发生了什么了。

    串行的情况下,吃饭在运行到sleep后,因为sleep,线程被挂起,并开始使用定时器计时。计时5s后,开始执行后面的语句以及喝酒。喝酒在运行到sleep后,因为sleep,线程被挂起,并开始使用定时器计时。计时5s后,开始执行后面的语句并且结束。因为sleep前后的语句运行速度非常快,基本可以忽略不计,所以总时间就是sleep的时间,也就是串行执行的10s。

    并发的执行吃饭和喝酒这两个线程,但是吃饭在运行到sleep后,因为sleep,线程被挂起,并开始使用定时器计时;同样,喝酒也因为sleep,线程被挂起,并开始使用定时器计时。而计时器是并行执行的,所以,一起执行5s后,吃饭和喝酒都重新回到了就绪状态,重新开始执行后面的语句。因为sleep前后的语句运行速度非常快,基本可以忽略不计,所以总时间就是sleep的时间,也就是并行执行的5s。

    综上所述,在阻塞的情况下,并行能够大大缩短运行时间。当然,这是在sleep阻塞的情况下,其他情况具体情况具体分析。

    案例参考文章:https://blog.csdn.net/vbirdbest/article/details/81282163

    展开全文
  • CPU、核心,进程线程串行、并发、并行

    注意看修饰词。

    1、计算机硬件基本组成

    一个计算机(冯·诺依曼结构)【主要】硬件组成:

    • 主板:是“交通枢纽”,各个部件工作的所在平台,它负责将各个部件紧密连接在一起,各部件通过主板进行数据传输
    • CPU:中央处理器(Central Processing Unit),决定电脑的性能等级。主要有3大组成部分
      • 运算器:算术逻辑运算单元(ALU,Arithmetic Logic Unit),负责执行所有的数学和逻辑工作
      • 控制器:控制单元(CU,Control Unit),控制计算机的所有其他部件,如输入输出设备以及存储器
      • 寄存器:存储单元,包括CPU片内缓存和寄存器组,是CPU中暂时存放数据的地方
    • 内存:将输入设备接收到的信息以二进制的数据形式存到存储器中
      • RAM
      • ROM
      • CMOS
    • 外存:辅助存储器,像硬盘等,能长期保存信息
    • 显卡、网卡、声卡、电源、键盘、鼠标、显示器等
      在这里插入图片描述

    win10下观察其内存动态使用图:
    在这里插入图片描述
    CPU是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit)。它的功能主要是解释计算机指令、处理计算机软件中的数据。
    在这里插入图片描述
    CPU工作原理图:
    在这里插入图片描述

    windows10下 CPU动态使用图:
    在这里插入图片描述
    上述这款CPU的 构造:
    在这里插入图片描述
    这就是我们购买电脑时,所看到的CPU参数:该电脑拥有1个CPU,它有4个内核(表示有4个相对独立的CPU核心单元组,这是物理概念)

    上述这个CPU可描述为:单CPU 4核心 4线程。4核 指的是物理核心(物理概念)。4线程(线程数是一个逻辑概念)。

    上述这个CPU不支持 超线程技术。超线程技术、虚拟化技术 是两个不同的东西。

    也可以通过cmd,wmiccpu get查看:

    • NumberOfCores:表示CPU核心数
    • NumberOfLogicalProcessors:表示CPU线程数

    多核 是指一个CPU有多个核心处理器,处理器之间通过CPU内部总线进行通讯。

    多CPU是指简单的多个CPU工作在同一个系统上,多个CPU之间的通讯是通过主板上的总线进行的。

    在这里插入图片描述

    参考文章:
    CPU个数,核心数,线程数

    2、进程(process)、线程(thread)

    在这里插入图片描述
    注意下方语句中的 主体:操作系统、CPU

    进程:操作系统(OS)进行资源(CPU、内存、磁盘、IO、带宽等)分配的最小单位;

    是OS对正在运行的程序的一种抽象,是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成。

    打开一个浏览器、一个聊天窗口分别是一个进程。进程可以有多个子任务,如聊天工具接收消息、发送消息,这些子任务是线程。
    资源分配给进程,线程共享进程资源。

    线程:CPU调度和分配的基本单位。
    一个进程可由多个线程的执行单元组成,每个线程都运行在同一进程的上下文中,共享同样的代码和全局数据。
    每个进程至少有一个主执行线程,它无需由用户主动创建,一般由系统自动创建。系统创建好进程后,实际上就启动了执行该进程的执行主线程,执行主线程以函数地址形式,即程序入口函数(如 main函数),将程序的启动点提供给操作系统。主执行线程终止了,进程也就随之终止。

    线程数 是一种逻辑概念,是模拟出的CPU核心数。

    进程和线程的关系:进程可以简单理解为一个容器,有自己独立的地址空间,其内部的各个线程共享该地址空间。
    其实严格讲应该是线程能够获得CPU资源,进程对CPU资源的获取也是体现在线程上的。至于CPU内核数,和进程线程没直接关系。操作系统(OS)可以把某个进程部署在某个CPU核上,当然这要取决于系统设计。

    线程是CPU调度和分配的最小单位,操作系统会根据进程的优先级和线程的优先级去调度CPU。一个计算机可以并发(同时)的线程数,等于计算机上的逻辑处理器的个数(CPU个数 *每个CPU核心数 *每个内核线程数)。

    进程、线程是操作系统调度的,进程本身不会负责调度线程。在操作系统看来,线程和进程其实差不多,不同点是线程是迷你的进程,并且进程可以包含多个线程。

    对比进程线程
    定义进程是程序运行的一个实体的运行过程,是系统进行资源分配和调配的一个独立单位线程是进程运行和执行的最小调度单位
    系统开销创建撤销切换开销大,资源要重新分配和收回仅保存少量寄存器的内容,开销小,在进程的地址空间执行代码
    拥有资产资源拥有的基本单位基本上不占资源,仅有不可少的资源(程序计数器,一组寄存器和栈)
    调度资源分配的基本单位独立调度分配的单位
    安全性进程间相互独立,互不影响线程共享一个进程下面的资源,可以互相通信和影响
    地址空间系统赋予的独立的内存地址空间由相关堆栈寄存器和和线程控制表TCB组成,寄存器可被用来存储线程内的局部变量

    线程切换

    • CPU给线程分配时间片(也就是分配给线程的时间),执行完时间片后会切换都另一个线程。

    • 切换之前会保存线程的状态,下次时间片再给这个线程时才能知道当前状态。

    • 从保存线程A的状态再到切换到线程B时,重新加载线程B的状态的这个过程就叫上下文切换

    • 而上下切换时会消耗大量的CPU时间。

    线程开销

    • 上下文切换消耗
    • 线程创建和消亡的开销
    • 线程需要保存维持线程本地栈,会消耗内存

    程序与进程、线程的关系

    程序 只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态的实体。
    而进程则不同,它是程序在某个数据集上的执行(即 进程是程序的一次执行),是一个动态的实体,有自己的生命周期,因创建而产生、因调度而运行、因等待资源或事件而被处于等待状态、因任务完成而被撤销,反映的是一个程序在一定的数据集上运行的全部动态过程。

    进程和程序并不是一一对应的:一个程序执行在不同的数据集上就成为不同的进程,可以用进程控制块来唯一地标识每个进程。这是程序无法做到的,因为程序没有和数据产生直接的联系,即使是执行不同的数据的程序,但它们的指令的集合依然是一样的,因此无法唯一地标识出这些运行在不同数据集上的程序。
    一般来说,一个进程肯定有一个与之对应的程序,而且只有一个。而一个程序有可能没有与之对应的进程(因为它没有执行)、也可能有多个进程与之对应(运行在不同的数据集上)。

    不同的进程可以执行同一段程序,比如读取同一个文件数据,它们的读取函数的代码是相同的,并被2个进程或线程运行了。

    一般情况下,写一个程序,没有单独开线程,那么默认这个程序的一次运行就是一个单进程;而如果调用了fork,这时将会有2个进程,调用thread,则这个进程就会有2个线程。

    进程是一个实体,每一个进程都有它自己的内存地址段(heap、stack等),进程是执行中的程序。

    程序是一个没有生命的实体,只有处理器赋予程序生命时,才能成为一个活动的实体。

    线程,程序执行的最小单元,每个程序都至少有一个线程,若程序只有一个线程,那就是它程序本身。单线程的进程可以简单地理解为只有一个线程的进程。一个进程在同一时间只做一件事,但有了多线程后,一个进程同一时间可以做多件事,每个线程可以处理不同的事务。无论系统有几个CPU,其实进程运行在单CPU上,多线程也可以是进程并发处理多个事务。一个线程阻塞不会影响另一个线程。

    多线程的进程可以尽可能地利用系统CPU资源,但也不是线程越多越好,线程越多,CPU分配给每个线程的时间就越少。

    线程 包含了表示进程内执行环节所必需的信息:标识线程的线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量、线程私有数据。
    对于内存而言,堆内存、代码区一般属于一个进程,但是栈却是属于一个线程的,且每个线程拥有一个独立的栈。
    errno也是属于单个线程的,每个线程中的errno是独立的。
    进程内所有信息对于线程是共享的,包括执行代码、全局变量、堆内存、栈、文件描述符。

    总结:
    进程和线程都是一个时间段的描述,是CPU工作时间段的描述:

    • 进程就是上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文
    • 线程是共享了进程的上下文环境,的更为细小的CPU时间段。

    3、串行、并发、并行

    这些概念对于进程、线程都适用。

    3.1、串行

    多个任务,执行时一个执行完再执行另一个。

    3.2、并发(concurrency)

    多个线程在单个核心运行,同一时间一个线程运行,系统不停切换线程,看起来像同时运行,实际上是线程不停切换。

    即一个指令 和另一个指令交错执行,操作系统实现这种交错执行的机制称为:上下文切换。上下文是指操作系统保持跟踪进程或线程运行所需的所有状态信息,如寄存器文件的当前值、主存内容等

    3.3、并行(parallelism)

    每个线程分配给独立的核心,线程同时运行。

    单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行);多核CPU线程间可以实现微观上并行。

    总结:
    1、单CPU中进程只能是并发,多CPU计算机中进程可以并行。
    2、单CPU单核中线程只能并发,单CPU多核中线程可以并行。
    3、无论是并发还是并行,使用者来看,看到的是多进程,多线程。

    4、CPU处理程序

    4.1、单核CPU处理程序

    在单CPU计算机中,有一个资源是无法被多个程序并行使用的:CPU。

    单进程多线程处理:

    在一个程序里,有两个功能:听歌、发送消息,这就是单进程2线程。如果听歌线程获取了锁,那么这个线程将获取CPU的运行时间,其他线程将被阻塞。但CPU始终处于运行状态,影响计算时间的其实只是加锁、解锁的时间,并不会发生CPU空闲的现象,CPU利用率100%。

    线程阻塞:一般是被动的,在抢占资源中得不到资源,被动的挂起在内存,等待某种资源或信号将它唤醒。(释放CPU,不释放内存)

    多进程处理:
    将听歌、发消息分别写出两个独立的程序,独立运行,与上面不同的是,如果进程间需要通信,比如交换数据,则会需要很多步骤,效率低。

    4.2、多核CPU处理程序

    单进程多线程处理:线程可以跨核处理,进程之间则不能,如同支付宝不能访问QQ一样(安全性)。
    跟单核对比:如果A核处理听歌线程阻塞,B核空闲,则CPU工作效率下降一半;没有阻塞时,QQ的A线程听歌、B线程发消息,多核CPU效率比单核快很多。

    多进程多线程处理:不同的程序,不可能一个进程融合QQ、支付宝、浏览器等

    多核下线程数量选择

    • 计算密集型
      程序主要为复杂的逻辑判断和复杂的运算。
      CPU的利用率高,不用开太多的线程,开太多线程反而会因为线程切换时切换上下文而浪费资源。

    • IO密集型
      程序主要为IO操作,比如磁盘IO(读取文件)和网络IO(网络请求)。
      因为IO操作会阻塞线程,CPU利用率不高,可以开多点线程,阻塞时可以切换到其他就绪线程,提高CPU利用率。

    总结:

    • 提高性能的一种方式:提高硬件水平,处理速度或核心数。
    • 另一种方式:根据实际场景,合理设置线程数,软件上提高CPU利用率。

    进程:处理任务多,每个进程都有独立的内存单元,占用CPU资源相对较少。缺点是 进程间切换开销大。进程之间通信就如同两个程序之间的通信。

    线程:处理任务相对较少,同时为了处理【并发】,多个线程共享内存单元,占用资源少。线程之间的通信就如同一个程序里的两个函数间通信,在函数里定义一个全局变量,两个线程(两个函数)都能用,线程间共享内存。

    展开全文
  •  并发、并行、串行、同步、异步、阻塞、非阻塞、进程线程、协程是并发编程中的常见概念,相似却也有却不尽相同,令人头痛,这一篇博文中我们来区分一下这些概念。 2 并发与并行  在解释并发与并行之前,我们...

    1 引言

      并发、并行、串行、同步、异步、阻塞、非阻塞、进程、线程、协程是并发编程中的常见概念,相似却也有却不尽相同,令人头痛,这一篇博文中我们来区分一下这些概念。

    2 并发与并行

      在解释并发与并行之前,我们必须先明确:单个处理器(一个单核CPU)在某一个时刻只能处理一个线程
      并发是指在同一个处理器上通过时间片轮转的方式在多个线程之间频繁切换,由于切换速度极快,所以看似多个线程似乎被同时执行,但实际上每一个时刻都只有一个线程被执行,其他的线程出于阻塞状态。
      并行是指多个处理器在同一时刻同时处理了多个不同的线程,这才是真正意义的同时被执行。
      如下图所示,线程A与线程B同在一个CPU内执行,且任一t时刻内,都只有一个线程(A或者B)被执行,所以线程A与线程B是并发执行的。线程C和线程D分别在两个CPU内执行,且在某一个t时刻内同时都在执行,所以线程C和线程D是并行的。

    3 并行与串行

      上面已经说到,并行是指多个任务同时执行,而串行是指多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个。
      所以,并发与并行是在某一时刻是否都在执行的区别。并行与串行是同时进行或一个结束才进行下一个的区别。

    4 同步与异步

      同步与异步的概念与消息的通知机制有关:
      同步是指线程在访问某一资源时,获得了资源的返回结果之后才会执行其他操作,否则主动继续获取这一资源;
      异步与同步相对,是指线程在访问某一资源时,无论是否取得返回结果,都进行下一步操作;当有了资源返回结果时,系统自会通知线程。

    用一个比喻来说明:10多前的银行是没有业务取号的,我们去办理业务时,如果有很多人,那就先排队,然后关注着什么时候轮到自己,这就是同步;现在去银行,得先取一张小纸条,上面写着你的
    业务号,轮到你的时候,银行会喊你,这就是异步。异步机制往往注册一个回调机制,在所等待的事件被触发时由触发机制(银行柜台业务员)通过某种机制(业务办理号码)找到等待该事件的人。

    5 阻塞与非阻塞

      阻塞是与非阻塞都是程序的一种运行状态。
      线程在等待某个操作完成期间,自身无法继续执行别的操作,则称该线程在该操作上是阻塞的。
      线程在等待某个操作完成期间,自身可执行别的操作,则称该线程在该操作上是非阻塞的。

    继续上面银行办理业务的例子,无论是10多年前的排队办理业务,还是现在的业务号办理业务,如果在我们在等待过程中,什么也不能做,那就是阻塞的;如果在等待过程中,可以做其他事情(看书
    、玩手游),那就是非阻塞的。

      同步和异步是个线程处理方式或手段,阻塞和非阻塞是线程的一种状态,两者并不相同也并不冲突。

      同步、异步与阻塞非阻塞可以产生不同的组合:同步阻塞、同步非阻塞、异步阻塞、异步非阻塞。

    还是银行办理业务的例子:如果排着队,且只能傻傻的排着队,看着什么时候到自己,那就是同步阻塞;如果排着队还能玩玩手机,偶尔抬头看看什么时候到自己,那就是同步非阻塞。如果是现在的
    取票按业务号办理业务,拿到号码后就陷入懵逼状态,啥也不能做,直到银行根据业务号通知自己,那就是异步阻塞;如果拿到业务号之后,自己爱干嘛干嘛,那就是异步非阻塞。

    6 进程 线程 协程

    6.1 基本概念

      进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位,是资源(内存)分配的最小单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
      线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
      协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

    6.2 进程与线程

      线程是指进程内的一个执行单元,也是进程内的可调度实体。线程与进程的区别:
      1) 地址空间:线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有自己独立的地址空间;
      2) 资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源;
      3) 线程是处理器调度的基本单位,但进程不是;
      4) 二者均可并发执行
      5) 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

    6.3 协程多与线程进行比较

      1) 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。
      2) 线程进程都是同步机制,而协程则是异步
      3) 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。

      参考资料:
      https://www.cnblogs.com/lxmhhy/p/6041001.html
      https://www.jianshu.com/p/3308311fb90c

    展开全文
  • 进程线程

    万次阅读 多人点赞 2021-03-17 22:50:20
    进程线程 1 进程 1.1 进程的概念 进程就是正在运行的程序,它代表了程序所占用的内存区域 1.2 进程的特点 独立性 进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间,在没有...
  • 当利用迅雷下载多个任务的时候,会发现多个任务都在同时下载,此时为了能够同时执行下载操作,迅雷就会创建多个线程,将不同的下载任务放到不同线程执行。 3.串行、并行 串行: 按顺序执行。在计算机...
  • C++ 线程串行 并行 同步 异步)详解 看了很多关于这类的文章,一直没有总结。不总结的话就会一直糊里糊涂,以下描述都是自己理解的非官方语言,不一定严谨,可当作参考。 首先,进程可理解成一个可执行文件的执行...
  • 线程串行通信 pdf

    2010-03-30 11:04:21
     在Win 32(95/NT)中,每一个进程可以同时执行多个线程,这意味着一个程序可以同时完成多个任务。对于象通信程序这样既要进行耗时的工作,又要保持对用户输入响应的应用来说,使用多线程是最佳选择。当进程使用多个...
  • 进程-线程-多线程 1、进程(process) 狭义定义:进程就是一段程序的执行过程 简单的来讲进程的概念主要有两点: 第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)...
  • 进程和线程的概念、区别及进程线程间通信

    千次阅读 多人点赞 2020-08-02 16:24:25
    进程与线程的概念,以及为什么要有进程线程,其中有什么区别,他们各自又是怎么同步的? 1. 基本概念: 进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发; 线程是进程的子...
  • 进程线程,并发和并行,串行,同步,异步概念解析 进程线程 一个操作系统运行多个进程,每个应用为一个进程,每个进程可以运行多个线程。这也就是并发编程。 操作系统控制进程,开发者控制线程。 并发和并行的...
  • 进程线程

    2016-03-29 10:02:07
    线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 一个线程可以创建和撤销另一个线程;同一
  • 什么是线程进程?这个问题一直困扰着我。经过多番查询、思考、总结之后,终于总结了下我自己比较通俗的说法,一块给大家说说: 1:进程是指系统正在运行的一个应用程序;每个进程之间是独立的,每个进程均运行在其...
  • 进程线程同步 进程通信

    千次阅读 2011-04-30 16:45:00
      一、进程/线程间同步机制。 临界区、互斥区、事件、信号量四种方式 临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别 1、临界区:通过对多...
  • Linux下sqlite3多线程串行模式

    千次阅读 2017-01-23 20:39:47
    sqlite3支持三种模式:单线程模式,多线程模式和串行模式。 模式可在编译,启动时或运行时设置,一般来讲,启动时的设置会覆盖编译时的设置,运行时则会覆盖启动时或编译时的设置。但是一旦单线程模式被设置之后就不...
  • 同一时间,CPU只能处理1条线程,只有1条线程在工作(执行),多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换),如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象。 任务分为同
  • 进程线程预热

    2018-08-26 11:08:35
    一个进程想要执行任务,就必须要有线程,每个进程至少要有一条线程,一个进程的所有任务都在线程执行线程只有彻底执行完A才能执行B,这就是线程的安全; 1、多线程:在一个进程中开启多条线...
  • 漫谈并行,串行,流水线,线程进程 在说并行串行流水线时,我们先要说一个概念双核四程,四核八程代表什么。 双核四程 指处理器中有两个核心, 但是利用了超线程技术,一个核心就有2个线程,所以两个核心就有4个...
  • 进程, 线程 1.????进程 ????什么是进程? 开发写的代码我们称为程序,那么将开发的代码运行起来。我们称为进程。 明白点: 当我们运行一个程序,那么我们将运行的程序叫进程。 ????精简重点???? ...
  • iOS中多线程知识总结:进程线程、GCD、串行队列、并行队列、全局队列、主线程队列、同步任务、异步任务等(有示例代码)进程正在运行中的程序被称作进程,负责程序运行的内存分配;每一个进程都有自己独立的虚拟...
  • 名词解释 进程(Process)和线程(thread):...线程:(1)共享所在进程的内存空间(2)共享可变对象的共享时,需要同步(使用synchronization关键字维护线程安全)。(3)有独立的运行时栈,就像一个普通的函数...
  • 进程线程的区别

    千次阅读 2018-12-21 15:19:18
    进程线程的区别 进程:指在系统中正在运行的一个应用程序;...线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。进程——资源分配的最小单位,线程——程序执行的最小单位。 ...
  • 软件开发,网站开发过程中经常有并发,并行这样的多线程处理与应用。因此,有必要对其进行了解与掌握。...简单点说,进程就是执行中的程序活动,是一个活动的实体。 多进程,就好比同时打开了Word,Excel和V...
  • 四种进程线程同步机制

    千次阅读 2011-10-06 00:15:32
    现在流行的进程线程同步互斥的控制机制,其实是由最原始最基本的4种方法实现的: 1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 2.互斥量:为协调共同对一个共享资源的...
  • 进程线程概念区别: 进程是操作系统资源分配的基本单位,线程是操作系统调度资源的基本单位。进程是正在运行的程序的实例,其实就是系统中正在运行的一个应用程序,线程是进程的一个实体。进程包含线程,线程共用...
  • linux 内核进程 线程

    千次阅读 2012-08-02 10:14:59
    Linux进程线程问题   http://www.54xue.com/w/19/n-28919.html    2010年8月15日,今天研究的是Linux的进程管理,昨天是内存寻址,感慨颇深啊,《深入理解Linux内核》这本书真是浪得虚名,根本没有说到问题...
  • Python进程线程协程那些事儿

    千次阅读 2018-06-22 16:57:09
    我们电脑的应用程序,都是进程,假设我们用的电脑是单核的,cpu同时只能执行一个进程。当程序处于I/O阻塞的时候,CPU如果和程序一起等待,那就太浪费了,cpu会去执行其他的程序,此时就涉及到切换,切换前要保存上一...
  • 线程 vs 进程

    万次阅读 多人点赞 2017-01-22 19:51:54
    进程线程的区别是很重要的一个知识点,也是面试中经常问到的。网上转载博客痕迹明显,且千篇一律。我简单提取下,记录下来,希望能帮到你。另外在 LeetCode 上也有关于此问题的讨论,可以直接浏览“Read more” ...
  • 线程顺序执行

    万次阅读 多人点赞 2019-11-23 11:43:57
    控制线程执行顺序 一、实现 本文使用了8种方法实现在多线程中让线程按顺序运行的方法,涉及到多线程中许多常用的方法,不止为了知道如何让线程按顺序运行,更是让读者对多线程的使用有更深刻的了解。使用的...
  • Python发挥不了多核处理器的性能(据说是受限于GIL,被锁住只能用一个CPU核心...测试代码如下,程序先后分别测试了串行运算、并行运算以及多线程和多进程执行同一个函数所花费的时间。 #! /usr/local/bin/python2

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,158
精华内容 26,463
关键字:

不同进程的线程只能串行执行