Python单线程、多线程、多进程

并发和并行

并发:单核CPU在不同时刻只执行一个任务,在同一时间段内,交替执行两个任务。
在这里插入图片描述

并行:双核CPU可以在同一时刻执行两个任务。
多核CPU的每个核心都可以独立执行一个任务,而且多个核心之间不会相互干扰。
在这里插入图片描述
并发+并行:所有核心都要并行工作,并且每个核心还要并发工作。
在这里插入图片描述

总之
单核CPU只能并发,无法并行;
多核CPU,并发和并行一般同时存在,它们都是提高CPU处理任务能力的重要手段。

Python 并发:多线程、多进程的实现

GIL:全局解释器锁(Global Interpreter Lock)是一个互斥锁,它只允许一个线程来控制Python解释器。在任何时间点只有一个线程可以处于执行状态。执行单线程程序的开发人员感受不到GIL的影响,但它可能是CPU限制型和多线程代码中的性能瓶颈。

GIL是解释器本身的单个锁,它增加了一条规则,即执行任何Python字节码都需要获取解释器锁。这可以防止死锁(因为只有一个锁)并且不会引入太多的性能开销。但是即使在具有多个CPU核心的多线程架构中,GIL一次只允许一个线程执行。

Python是运行在解释器中的语言,python中的全局锁(GIL),在使用多进程(Thread)的情况下,不能发挥多核的优势。而使用多进程(Multiprocess),则可以发挥多核的优势真正地提高效率。

处理GIL
(1)使用多进程代替多线程。每个Python进程都有自己的Python解释器和内存空间,因此GIL不会成为问题。Python中的(Multiprocess)模块可以轻松创建进程。

在python多线程下,每个线程的执行方式是:
1、获取GIL
2、执行代码知道sleep或者python虚拟机将其挂起
3、释放GIL
可见,每个线程想要执行,必须拿到GIL,并且在python进程中,GIL只有一个。

python下想要充分利用多核CPU,就用多进程。
原因在于:每个进程有各自独立的GIL,互不干扰,这样就可以实现真正意义上的并行。所以在多核CPU中,多进程执行效率优于多进程(仅针对多核CPU而言)。

(2)更换Python解释器。Python有多个解释器。分别用C、Java、C#和Python写的CPython、Jython、IronPython和PyPy是最受欢迎的。GIL仅存在于CPython的原始Python实现中。(CPython使用最广,怎样判断自己的解释器)
(3)等待。虽然许多Python用户利用了GIL的单线程性能优势。多线程程序员不必烦恼,因为Python社区中一些最聪明的人正在努力从CPython中删除GIL。

Thread中的join方法 : join方法底层其实就是一个wait方法。

jion()阻塞主线程

  • jion()作用为阻塞主线程,在子线程未返回的时候,主线程等待其返回然后继续执行
  • jion不能与star在循环里连用

以下为错误代码,代码创建了5个线程,然后用一个循环激活线程,激活之后令其阻塞主线程

threads = [Thread() for i in range(5)]
for thread in threads:
     thread.start()
     thread.join()

执行过程:
1、第一次循环中,主线程通过start函数激活线程1,线程1进行计算
2、由于start函数不阻塞主线程,在线程1进行运算的同时。主线程向下执行jion函数
3、执行jion函数之后,主线程被线程1阻塞,在线程1返回结果之前,主线程无法执行下一轮循环
4、线程1计算完成之后,解除对主线程的阻塞
5、主线程进入下一轮循环,激活线程2并被阻塞
如此往复,可以看出,本来应该并发五个线程,在这里变成顺序队列,效率和单线程无异

jion的正确用法:使用两个循环分别处理start和jion函数,即可实现并发

threads = [Thread() for i in range(5)]
for thread in threads:  //A循环
    thread.start()
for thread in threads://B循环
    thread.join()

执行过程:
1、A循环中,依次开启线程1~线程5,,线程1到线程5并发执行
2、B循环中,线程1到线程5依次对主线程进行阻塞
3、线程1到线程5执行结束,依次解除对主线程的阻塞。
4、线程1到线程5全部执行完毕,主线程开始运行。

单线程

import requests
import time
from threading import Thread
from multiprocessing import Process

def count(x, y): //定义CPU密集的计算函数
    # 使程序完成50万计算
    c = 0
    while c < 500000:
        c += 1
        x += x
        y += y

def write(): //定义IO密集的文件读写函数
    f = open("test.txt", "w")
    for x in range(5000000):
        f.write("testwrite\n")
    f.close()
def read():
    f = open("test.txt", "r")
    lines = f.readlines()
    f.close()

_head = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'}
url = "http://www.tieba.com"
def http_request():  //定义网络请求函数
    try:
        webPage = requests.get(url, headers=_head)
        html = webPage.text
        return {"context": html}
    except Exception as e:
        return {"error": e}

测试线性执行IO密集操作、CPU密集操作所需时间、网络请求密集型操作所需时间

# CPU密集操作
t = time.time()
for x in range(10):
    count(1, 1)
print("Line cpu", time.time() - t)
# IO密集操作
t = time.time()
for x in range(10):
    write()
    read()
print("Line IO", time.time() - t)
# 网络请求密集型操作
t = time.time()
for x in range(10):
    http_request()
print("Line Http Request", time.time() - t)

多线程: from threading import Thread

counts = []  //测试多线程并发执行CPU密集操作所需时间
t = time.time()
for x in range(10):
    thread = Thread(target=count, args=(1,1))
    counts.append(thread)
    thread.start()
e = counts.__len__()
while True:
    for th in counts:
        if not th.is_alive():
            e -= 1
    if e <= 0:
        break
print(time.time() - t)

def io():  //测试多线程并发执行IO密集操作所需时间
    write()
    read()

t = time.time()
ios = []
t = time.time()
for x in range(10):
    thread = Thread(target=count, args=(1,1))
    ios.append(thread)
    thread.start()

e = ios.__len__()
while True:
    for th in ios:
        if not th.is_alive(): //判断所有线程是否执行完毕
            e -= 1
    if e <= 0://所有线程执行完毕
        break
print(time.time() - t)

t = time.time()   //测试多线程并发执行网络密集操作所需时间
ios = []
t = time.time()
for x in range(10):
    thread = Thread(target=http_request)
    ios.append(thread)
    thread.start()

e = ios.__len__()
while True:
    for th in ios:
        if not th.is_alive():
            e -= 1
    if e <= 0:
        break
print("Thread Http Request", time.time() - t)

多进程:from multiprocessing import Process
multiprocessing模块通过使用创建子进程,有效地避开了全局解释器锁(GIL),允许程序员充分利用机器上的多个处理器。

counts = [] //测试多进程并发执行CPU密集操作所需时间
t = time.time()
for x in range(10):
    process = Process(target=count, args=(1,1))
    counts.append(process)
    process.start()
e = counts.__len__()
while True:
    for th in counts:
        if not th.is_alive():
            e -= 1
    if e <= 0:
        break
print("Multiprocess cpu", time.time() - t)

t = time.time()  //测试多进程并发执行IO密集型操作
ios = []
t = time.time()
for x in range(10):
    process = Process(target=io)
    ios.append(process)
    process.start()

e = ios.__len__()
while True:
    for th in ios:
        if not th.is_alive():
            e -= 1
    if e <= 0:
        break
print("Multiprocess IO", time.time() - t)

t = time.time()  //测试多进程并发执行Http请求密集型操作
httprs = []
t = time.time()
for x in range(10):
    process = Process(target=http_request)
    ios.append(process)
    process.start()

e = httprs.__len__()
while True:
    for th in httprs:
        if not th.is_alive():
            e -= 1
    if e <= 0:
        break
print("Multiprocess Http Request", time.time() - t)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/441311.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

typescript学习(更新中)

目录 开发环境搭建类型如何声明有哪些类型编译配置文件 开发环境搭建 npm i -g typescripttsc检查是否安装成功 类型如何声明 // 先声明再赋值 let a: number a 1// 直接赋值 let b 1function sum(a: number, b: number): number {return a b } console.log(sum(1, 2))有…

linux 将 api_key设置环境变量里

vi ~/.bashrc在最后添加api_key的环境变量 export GEMINI_API_KEYAIza**********WvpX7FwbdM刷新配置 source ~/.bashrc使用python 读取环境变量 import os gemini_api_key os.getenv(GEMINI_API_KEY) print(gemini_api_key)

Mysql的Cardinality值

什么是Cardinality值&#xff1f; Cardinality值是Mysql做索引优化时一个非常关键的值&#xff0c;优化器会根据这个值来判断是否使用这个索引&#xff0c;它表示索引中唯一值的数目估计值&#xff0c;该值应该尽可能接近1&#xff0c;如果非常小&#xff0c;则用户需要考虑是否…

企业计算机服务器中了mkp勒索病毒如何解密,mkp勒索病毒解密流程

网络技术的应用与发展&#xff0c;为企业的生产运营提高了效率&#xff0c;越来越多的企业利用网络开展多项工作业务&#xff0c;利用网络的优势&#xff0c;可以为企业更好的服务&#xff0c;但是稍不注意就会被网络威胁所盯上。近日&#xff0c;云天数据恢复中心接到多家企业…

二本双非|逆袭985/211只要做好这3件事

我的本科学校就是双非&#xff0c;但是我并不觉得考研是一件非常容易地事情&#xff0c;并且我身边的同学也没有一个觉得考研很轻松。可能网上很多经验贴说自己双非上岸985&#xff0c;二本上岸985&#xff0c;我觉得这是大家陷入了互联网时代的信息茧房。 考研不管是对985/211…

波奇学Linux: 信号捕捉

sigaction:修改信号对应的handler方法 act输入型参数&#xff0c;oldact输出型参数 void (*sa_handler) (int) //修改的自定义函数 sigset_t sa_mask // void handler(int signo) {cout<<"catch a signal, signal number: "<<signo<<endl; } int …

超市小程序有哪些功能 怎么制作

超市小程序是非常有用的工具&#xff0c;可以帮助超市提升用户体验&#xff0c;提高销售额。下面我们来看一下超市小程序可以具备哪些功能&#xff0c;以及如何制作一个高效的超市小程序。 1. **商品展示与搜索功能**&#xff1a;用户可以浏览超市的商品信息&#xff0c;包括价…

数字化转型导师坚鹏:大模型的应用实践(金融)

大模型的应用实践 ——开启人类AI新纪元 打造数字化转型新利器 课程背景&#xff1a; 很多企业和员工存在以下问题&#xff1a; 不清楚大模型对我们有什么影响&#xff1f; 不知道大模型的发展现状及作用&#xff1f; 不知道大模型的针对性应用案例&#xff1f; 课程…

雍禾医疗耀眼的“小”医生,雍禾植发刘树伟10年热爱一份事业

“你说你一个普外科大大夫&#xff0c;怎么改去做小小毛发医生了呢&#xff1f;”这是雍禾植发刘树伟医生&#xff0c;从公立医院转行做毛发医生时&#xff0c;被人质疑最多的点。然而&#xff0c;选择成为一名毛发医生&#xff0c;却是他花3年时间做出的重要的决定。 2009年&…

【C++ STL详解】——string类

目录 前言 一、string类对象的常见构造 二、string类对象的访问及遍历 1.下标【】&#xff08;底层operator【】函数&#xff09; ​编辑 2.迭代器 3.范围for 4.at 5.back和front 三、string类对象的容量操作 1.size 和 length 2.capacity 3.empty 4.clear 5.res…

【校园安全】支小蜜防校园霸凌语音识别系统的好处

在校园安全领域&#xff0c;防校园霸凌语音识别系统的出现&#xff0c;为预防和应对校园霸凌行为提供了新的技术手段。本文将探讨防校园霸凌语音识别系统的好处&#xff0c;并分析其在校园安全建设中的重要作用。 通过安装在校园各个角落的语音识别设备&#xff0c;系统能够捕…

Flink并行度

1、Task flink中每个算子就是一个Task&#xff0c;比如flatMap、map、sum是一个Task。 2、SubTask 算子有几个并行度SubTask的数量就是几&#xff0c;比如 3、算子并行度 算子并行度指的是每个算子的并行度&#xff0c;可用env.setParallelism(1);设置所有算子的并行度&am…

浏览器是如何渲染页面的?

浏览器是如何渲染页面的&#xff1f; 1. 解析 HTML2. 样式计算 Computed Style3. 布局 Layout4. 分层 Layer5. 绘制 Paint6. 分块 Tiling7. 光栅化 Raster8. 画 draw完整过程面试题什么是 reflow&#xff08;回流/重排&#xff09;?什么是 repaint &#xff08;重绘&#xff0…

智慧城市中的数字孪生:构建城市管理的未来框架

目录 一、引言 二、数字孪生技术概述 三、数字孪生技术在智慧城市中的应用 1、实时监测与预警 2、模拟与优化 3、智能化决策 4、协同与共享 四、数字孪生技术构建城市管理的未来框架的价值 1、提高管理效率 2、优化资源配置 3、提升公共服务水平 4、增强应对突发事…

【Linux】Linux——Centos7安装

目录 虚拟机安装【空壳子】安装VMware Workstation新建虚拟机硬件兼容性(直接下一步)稍后安装操作系统客户及操作系统选择Linux&#xff0c;版本Centos764位给虚拟机命名&#xff0c;并选择安装位置处理器配置&#xff08;默认即可&#xff0c;不够用后面可以调&#xff09;虚拟…

JavaWeb - 3 - JavaScript(JS)

JavaScript(JS)官方参考文档&#xff1a;JavaScript 教程 JavaScript&#xff08;简称&#xff1a;JS&#xff09;是一门跨平台、面向对象的脚本语言&#xff0c;是用来控制网页行为的&#xff0c;它能使网页可交互&#xff08;脚本语言就不需要编译&#xff0c;直接通过浏览器…

谷歌广告(google Ads)投放技巧

Google广告投放涉及多个方面&#xff0c;以下是一些常用的技巧&#xff0c;可以帮助提高广告效果&#xff1a; 关键词选择&#xff1a; 选择与你的产品或服务紧密相关的关键词&#xff0c;并确保这些关键词与用户的搜索意图匹配。使用Google关键词规划工具来找到潜在的关键词&a…

python词嵌入

一、词嵌入的概念 自然语言处理的突破在2023年震撼世界&#xff0c;chatgpt3出来&#xff0c;之后chatgpt4、Gemini、Claude3等出来&#xff0c;问答越来越智能&#xff0c;非常厉害&#xff0c;其中有个基础性的概念&#xff0c;计算机要如何理解语言&#xff0c;基础工作就在…

IOS苹果通话记录在线生成网站源代码,直接上传就可使用

一键生成&#xff0c;PHP的上传到网站根目录打开域名访问即可 源码免费下载地址专业知识分享社区-专业知识笔记免费分享 (chaobiji.cn)

个人开发者如何制作实用的微信预约小程序?

随着移动互联网的普及&#xff0c;微信小程序已经成为一种非常流行的应用方式。在本文中&#xff0c;我们将介绍如何通过乔拓云平台制作一个微信预约小程序&#xff0c;从入门到精通&#xff0c;让你轻松完成这个过程。 一、注册登录乔拓云平台 首先&#xff0c;你需要在乔拓云…