首页 > 系统相关 >32. 线程、进程与协程

32. 线程、进程与协程

时间:2024-11-15 18:08:32浏览次数:1  
标签:__ 协程 32 start 线程 time 进程 CPU

一、什么是多任务

  如果一个操作系统上同时运行了多个程序,那么称这个操作系统就是 多任务的操作系统,例如:Windows、Mac、Android、IOS、Harmony 等。如果是一个程序,它可以同时执行多个事情,那么就称为 多任务的程序

  一个 CPU 默认可以执行一个程序,如果想要多个程序一起执行,理论上就需要多个 CPU 来执行。

  如果一个 CPU 是一个核心,理论上只能同时运行一个任务,但是事实上却可以运行很多个任务。这是因为操作系统控制着 CPU,让 CPU 做了一个特殊的事情,一会运行一个任务,然后快速的运行另一个任务,依次类推,实现了多个任务,看上去 “同时” 运行多个任务。

并发:是一个对假的多任务的描述;

并行:是真的多任务的描述;

二、进程与线程

  计算机程序只是存储在磁盘上的可执行二进制(或其它类型)文件。只有把它们加载到内存中从被操作系统调用,才拥有其生命期。

  进程(process)则是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其它用于跟踪执行的辅助数据。操作系统管理其上所有进程的执行,并为这些进程合理分配时间。进程也可以通过派生新的进程来执行其它任务,不过因为每个新进程也都拥有自己的内存和数据栈等,所以只能采用进程间通信的方式共享数据;

  线程(thread)与进程类似,不过它们是同一个进程下执行的,并共享相同的下上文。线程包括开始、执行顺序和结束三部分。它有一个指令指针,用于记录当前运行的上下文。当其它线程运行时,它可以被抢占(中断)和临时挂起(也称为睡眠)—— 这种做法叫做让步(yielding)。

  一个进程中的各个线程与主线程共享同一片数据空间。线程一般是以并发方式执行的。在单核 CPU 系统中,因为真正的并发是不可能的,所以线程的执行实际上是这样规划的:每个线程运行一小会,然后让步给其它线程(再次排队等待更多的 CPU 时间)。在整个进程的执行过程中,每个线程执行它自己特定的任务,在必要时和其它线程进行结果通信。

  但是这种共享数据也是存在风险的。如果两个或多个线程访问同一片数据,由于数据访问顺序不同,可能导致结果不一致。这种情况通常称为 “竞态条件”(race condition)。另一个需要注意的问题时,线程无法给予公平的执行时间。这是因为一些函数会在完成前保持阻塞状态,如果没有专门为多线程情况进行修改,会导致 CPU 的时间分配向这些贪婪的函数倾斜。

  在实现多任务时,线程切换从系统层面远不止保存和恢复 CPU 上下文这么简单。操作系统为了程序运行的高效性,每个线程都有自己缓存 Cache 等数据。操作系统还会帮你做这些数据的恢复操作。所以线程的切换比较耗性能。但是协程的切换只是单纯的操作 CPU 的上下文。

线程是计算机中可以被 CPU 调度的最小单元,进程是计算机资源分配的最小单元;进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域;

一个程序,至少有一个进程,一个进程中至少有一个线程,最终是线程在工作;

一个进程内可以开设多个线程,在用一个进程内开设多个线程无需再次申请空间及拷贝代码的操作,开设线程的开销远远的要小于进程的开销;

单核 CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务。但是因为 CPU 时间单元特别短,因此感觉不出来;

三、多进程的使用场景

  多进程 适合 计算密集型 的场景。

【1】、多进程的使用

import os, time

from multiprocessing import Process

def task():
    val = 1
    for i in range(1, 100000):
        val *= i


if __name__ == "__main__":
    l = []

    count = int(os.cpu_count())
    print(f"当前计算机CPU核心个数:{count}")

    start_time = time.time()

    for i in range(count):
        p = Process(target=task)
        p.start()
        l.append(p)

    for p in l:
        p.join()

    print(f"运行时间:{time.time() - start_time}")

【2】、多线程的使用

import os, time

from threading import Thread

def task():
    val = 1
    for i in range(1, 100000):
        val *= i


if __name__ == "__main__":
    l = []

    count = int(os.cpu_count())
    print(f"当前计算机CPU核心个数:{count}")

    start_time = time.time()

    for i in range(count):
        t = Thread(target=task)
        t.start()
        l.append(t)

    for t in l:
        t.join()

    print(f"运行时间:{time.time() - start_time}")

四、多线程的使用场景

  多线程 适合 IO 密集型 场景

【1】、多进程的使用

import time

from multiprocessing import Process

def task():
    time.sleep(3)

if __name__ == "__main__":
    l = []
    start_time = time.time()

    for i in range(1000):
        p = Process(target=task)
        p.start()
        l.append(p)

    for p in l:
        p.join()

    print(f"运行时间:{time.time() - start_time}")

【2】、多线程的使用

import time

from threading import Thread

def task():
    time.sleep(3)

if __name__ == "__main__":
    l = []
    start_time = time.time()

    for i in range(1000):
        t = Thread(target=task)
        t.start()
        l.append(t)

    for t in l:
        t.join()

    print(f"运行时间:{time.time() - start_time}")

标签:__,协程,32,start,线程,time,进程,CPU
From: https://www.cnblogs.com/FlurryHeart/p/18548435

相关文章

  • STM32一种计算CPU使用率的方法及其实现原理
    本文将以STM32F429+FreeRTOS+KEIL为测试环境,看下MCU的使用率1、计算STM32使用率的官方方法在其CubeMX的固件库中2、加入自己的工程2.1、文件cpu_utils.c有描述使用的步骤2.2、实操一遍第一步:将上图中的cpu_utils.c文件添加到工程中,并将其头文件路径加......
  • STM32项目实战:基于STM32U5的智能大棚温控系统(LVGL),附项目教程/源码
    《智能大棚温控系统_STM32U5》项目完整文档、项目源码,点击下方链接免费领取。项目资料领取https://s.c1ns.cn/F5XyUSTM32项目实战之“智能大棚温控系统”(基于STM32U5)今天小编来分享一个《智能大棚温控系统》的项目案例,硬件平台是STM32U5开发板+资源扩展板+显示触摸屏+仿真器,项......
  • 基于stm32的bacnet协议
    bacnet协议对于国内网站来说,几乎可以说资料为零,通俗大论一遍,具体操作方法屁都没说先从工具说起开发工具BACnetScan:(讯绕提供)(工具1)链接:https://pan.baidu.com/s/1TJxc0xaEsCT3lJOlG78B7w提取码:t7bwYabe:(工具2)链接:https://pan.baidu.com/s/1jfsbGQwv08GISF0VeOjY_g提取码:mmdc......
  • 力扣-Mysql-3293-计算产品最终价格(中等)
    一、题目来源3293.计算产品最终价格-力扣(LeetCode)二、数据表结构表:Products+------------+---------+|ColumnName|Type|+------------+---------+|product_id|int||category|varchar||price|decimal|+------------+-------......
  • 2024-2025-1 20241322《计算机基础与程序设计》第八周学习总结
    2024-2025-120241322《计算机基础与程序设计》第八周学习总结作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK08这个作业的目标功能设计与面向对象......
  • 线程间通信
    使用锁+信号量+队列,可以实现线程间通信。 下面是一个生产者,消费者的例子。 #include<iostream>#include<queue>#include<thread>#include<mutex>#include<condition_variable>#include<chrono>//定义一个消息类型structMessage{intdata;};......
  • 多线程篇·线程相关知识
    一、线程状态线程是cpu任务调度的最小执行单位,每个线程拥有自己独立的程序计数器、虚拟机栈、本地方法栈。线程状态包括:创建、就绪、运行、阻塞、死亡。二、线程状态切换三、阻塞唤醒过程阻塞以下三个方法的调用都会使当前线程阻塞,该线程将会被放置到对该Object的请......
  • 多线程篇·线程相关知识
    一、线程状态线程是cpu任务调度的最小执行单位,每个线程拥有自己独立的程序计数器、虚拟机栈、本地方法栈。线程状态包括:创建、就绪、运行、阻塞、死亡。二、线程状态切换三、阻塞唤醒过程阻塞以下三个方法的调用都会使当前线程阻塞,该线程将会被放置到对该Object的请......
  • 玩转Mixly之ESP32的舵机
    SG90舵机舵机参数产品类型:SG90舵机产品扭矩:2.0kg/cm(4.8V),2.2kg/cm(6V)产品速度:0.09秒/60°(4.8V),0.08秒/60°(6V)转动角度:180°工作电压:4.8~6V齿轮形式:塑料齿轮死区设定:7us(微秒)产品重量:10.5g产品尺寸:22.8mm×12.2mm×28.5mm舵机实物图线序图始终记住......
  • 线程状态切换
    Java线程控制方法的作用及其区别:start:作用:启动线程,由虚拟机自动调度执行run()方法。区别:线程处于就绪状态。run:作用:线程逻辑代码块处理,JVM调度执行。区别:线程处于运行状态。sleep:作用:让当前正在执行的线程休眠(暂停执行)。区别:不释放锁。wait:......