首页 > 其他分享 >11月2日GIL机制、计算密集型和io密集型

11月2日GIL机制、计算密集型和io密集型

时间:2023-11-02 20:14:47浏览次数:40  
标签:11 __ 多线程 list start 密集型 io time GIL

目录

CPython

CPython是Python的一种实现,它是官方解释器之一,而Python是编程语言本身的名称。然后CPython里面就有一个机制GIL(全局解释器锁),它是CPython中的一个重要特性,它对多线程程序的执行方式产生了影响。

GIL机制

什么是GIL机制?

1.在python解释器中有一把GIL锁,它的本质是一把互斥锁。

因为GIL锁的存在同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势

2.GIL可以比喻成执行权限,同一进程下的所有线程要想执行都需要抢这个权限

3.GIL是CPython中的一个机制叫做全局解释器锁。

Jython、IronPython 和 PyPy(了解)

  1. Jython:
    • Jython 是 Python 在 Java 平台上的实现。
    • 它将 Python 代码编译成 Java 字节码,从而可以与 Java 代码集成,并直接使用 Java 生态系统的各种库和工具。
    • Jython 具有与 CPython 不同的特性和行为,因为它在 Java 虚拟机上运行,不受 GIL 的限制。
  2. IronPython:
    • IronPython 是 Python 在 .NET 平台上的实现。
    • 它可以与 .NET 语言(如 C#)相互调用,并利用 .NET 生态系统的各种库和工具。
    • 类似于 Jython,IronPython 不受 GIL 的限制。
  3. PyPy:
    • PyPy 是一种 Python 解释器,其目标是提供更高的性能。
    • PyPy 使用即时编译技术,可以加速 Python 代码的执行速度,相对于 CPython,它通常更快。
    • 尽管 PyPy 仍然具有 GIL,但由于其性能改进,它在某些情况下可以更好地处理多线程并发。

同时这三个不受GIL机制的影响

为什么要有GIL机制

在并发编程里面垃圾回收机制需要有GIL机制来保证安全

这个GIL了解就行了,就当扩展看看。

例子

我现在有四个任务需要处理,处理方式肯定是要玩出并发的效果,解决方案:

方案一:开启四个进程

方案二:一个进程下,开启四个线程

下面给出具体类型:

计算密集型

每个都要计算10s

多线程:

在同一时刻只有一个线程会被执行,也就意味这每个10s都不能省,分开每个都要计算10s,共40s

测试代码如下:

import time
from threading import Thread


# 计算密集型(多线程)
def work1():
    res = 0
    for i in range(100000000):
        res += 1


if __name__ == '__main__':
    t_list = []
    start = time.time()  # 这里输出开始的时间
    for i in range(4):
        t = Thread(target=work1)
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    end = time.time()

    print('多线程', end - start)  # 多线程运行这个跑了14.351047039031982秒

多进程:

可以并行的执行多个线程,10s+开启进程的时间

测试代码入如下:

import time
from multiprocessing import Process


# 计算密集型(多进程)
def work1():
    res = 0
    for i in range(100000000):
        res += 1


if __name__ == '__main__':
    t_list = []
    start = time.time()  # 这里输出开始的时间
    for i in range(4):
        t = Process(target=work1)
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    end = time.time()

    print('多进程', end - start)  # 多进程运行此代码用了4.870921611785889秒

这两个代码的比拼结果如下

通过结果说明了这个集型适合用多进程

io(输入/输出)密集型

4个任务每个任务90%大部分时间都在io

每个任务io10s

多线程:

可以实现并发,每个线程io的时间不咋占用CPU,10s + 4个任务的计算时间

测试代码如下:

# io密集型(多线程)
import time
from threading import Thread


def work1():
    x = 1 + 1
    time.sleep(5)


if __name__ == '__main__':
    t_list = []
    start = time.time()  # 这里输出开始的时间
    for i in range(4):
        t = Thread(target=work1)
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    end = time.time()

    print('多线程', end - start)

多进程:

可以实现并行,10s + 1个任务执行的时间+开启进程的时间

测试代码如下:

# io密集型(多线程)
import time
from threading import Thread


def work1():
    x = 1 + 1
    time.sleep(5)


if __name__ == '__main__':
    t_list = []
    start = time.time()  # 这里输出开始的时间
    for i in range(4):
        t = Thread(target=work1)
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    end = time.time()

    print('多线程', end - start)

两者结果对比图

虽然就这一点点的时间差距问题,io密集型还是适合多线程

标签:11,__,多线程,list,start,密集型,io,time,GIL
From: https://www.cnblogs.com/slzjb/p/17806178.html

相关文章

  • 19.10 Boost Asio 同步文件传输
    在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含goodbyelyshark关键词来验证文件是否传输结束了,当然了这种传输方式明显没有根据长度传输严谨,但使用这种方式也存在一个有点,那就是无需确定文件长度,因为无需......
  • CF1868B2 Candy Party (Hard Version) 题解
    Problem-1868B2-CodeforcesCandyParty(HardVersion)-洛谷相信大家已经看过SimpleVersion,这题和上题不同之处就在于如果\(b_i=2^x\),他可以被分解成\(2^x\)或\(2^{x+1}-2^x\),我们不妨起初固定一种方案,如果不满足条件后再把一部分换回去。我们强制钦定起......
  • 大学生创新训练项目开发日志 (10-26 ~ 11-2)
    进展资源钩取我们通过如下方法对资源钩取模块进行了改进:对getDrawable()返回的Drawable实例进行了进一步处理,降低被丢弃的资源的比率。通过LayoutInflater.inflate()返回的ImageView实例的getDrawable()方法获取该实例内含的Drawable资源。进行了如下改进后,对......
  • 19.10 Boost Asio 同步文件传输
    在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含goodbyelyshark关键词来验证文件是否传输结束了,当然了这种传输方式明显没有根据长度传输严谨,但使用这种方式也存在一个有点,那就是无需确定文件长度,因为无需......
  • 11.2
    今天我们来实现上次期中考试的代码,本次实现的是后端 Pojo类1、Plan.java类packagecom.example.pojo;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.time.LocalDateTime;importjava.util.List;@Data@AllArgs......
  • 11.2
    11.2数据类型(内置)内置数据类型字符整型浮点型布尔类型表示真假#include<stdbool.h>_Boolflag=true;_Boolunflag=false;signedorunsignedsigned表示一个类型带有正负号unsigned表示不带正负号,能表示的位数更大void类型转换隐式类型转......
  • 11.1
    今天实现了期中考试的代码。以下是本次期中考试的题目企业ERP生产计划管理系统(20分)1、项目需求:随着企业规模的不断扩大和市场竞争的日益激烈,生产计划管理成为了企业管理中不可或缺的一部分。生产计划管理子系统是企业管理信息系统中的一个重要组成部分,它主要负责生产计划的制定......
  • Spring,IOC创建对象的方式,无参有参
    创建一个spring模块,创建有无参构造的User实体类  方式一、无参构造创建对象  (默认的)我们知道:创建对象是调用了实体类中的构造方法的Spring这边通过配置文件也是默认调用了无参构造 二、有参构造创建对象用法1、通过下标赋值  index=“0” 因为User中就一个nam......
  • P9740 「KDOI-06-J」ION 比赛 题解
    题目思路:先计算总分数\(sum\),\(c_i=\frac{100}{a_i}\)为每道题的每个测试点分数。如果总分数达到\(Au\)线,直接输出AlreadyAu.。否则计算到达\(Au\)线还需多少分\(p\),遍历所有题,求出每道题的失分,如果失分大于等于\(p\),则输出\(\lceil\frac{p}{c_i}\rceil\),即至......
  • 11月1日线程锁
    目录线程锁下面用进程锁解决这个问题修改比喻线程锁为什么会有线程锁,首先这里说一个例子假设我的计算机的CPU略微拉跨一点,然后我有个三个线程进行计算,同时计算量都不小,这时候就有可能出现算错的情况具体代码如下fromthreadingimportThreadx=0deftask():globa......