守护?全局解释器锁?Python那些若隐若现的进程线程知识-开发技巧IX

        篇主在web开发中其实用得不多。在当下云平台盛行,依靠平台能力,CI/CD式做法开多个worker工作进程完事,除一些监控日志插件会用多线程多进程,web开发是比较少用的。

        先讲一个python开发都听过的:GIL,即全局解释器锁。

目录

GIL全局解释器锁

Python多进程 多线程 协程

Python守护进程 守护线程

鸭子模型

runserver运行时启动的两个线程是为什么


GIL全局解释器锁

        GIL(全局解释器锁,Global Interpreter Lock)是 CPython 解释器中的一种同步机制,用于限制多线程在同一时刻只能有一个线程执行 Python 字节码。GIL 的存在是为了简化内存管理和解决多线程中的数据竞争问题。

        然而,GIL 也导致了 CPython 中的多线程无法充分利用多核 CPU,因此在 CPU 密集型任务中表现不佳。对于 I/O 密集型任务,可以使用多线程、协程或异步 I/O 来实现并发。对于 CPU 密集型任务,可以考虑使用多进程来充分利用多核 CPU。

        实验:以下是拿python3.6做的使用,单线程和多线程情况下,执行时间十分之相近。(查网上有不少执行结果是还不如单线程的执行时间)
        注:GIL仅适用于CPython解释器。如用Jython和IronPython,并未实现GIL,因此在这些实现中,多线程性能可能会更好。

import threading
import timedef count(n):while n > 0:n -= 1# 单线程执行
start_time = time.time()
count(100000000)
end_time = time.time()
print("单线程执行时间:", end_time - start_time)  # 单线程执行时间: 4.452801704406738# 多线程执行
start_time = time.time()
t1 = threading.Thread(target=count, args=(50000000,))
t2 = threading.Thread(target=count, args=(50000000,))
t1.start()
t2.start()
t1.join()
t2.join()
end_time = time.time()
print("多线程执行时间:", end_time - start_time)  # 多线程执行时间: 4.272630214691162

Python多进程 多线程 协程

  1. 多线程:Python 标准库中的 threading 模块提供了多线程支持(上面的实验就是使用的它)。由于全局解释器锁(GIL)的存在,CPython 中的多线程无法充分利用多核 CPU,因此在 CPU 密集型任务中表现不佳。但在 I/O 密集型任务中,多线程可以提高程序的执行效率。

  2. 多进程:Python 的 multiprocessing 模块提供了多进程支持。多进程可以充分利用多核 CPU,适用于 CPU 密集型任务。然而,进程间通信和资源共享相对复杂,开销较大。

  3. 协程:协程是一种轻量级的并发策略,它允许在一个线程内部实现多个任务的并发执行。协程通过异步 I/O 和 async/await 语法实现。Python 的 asyncio 模块提供了协程支持。协程适用于 I/O 密集型任务,如网络请求、文件读写等。

多进程实验:

import multiprocessing
import timedef count(n):while n > 0:n -= 1def main1():# 单进程执行start_time = time.time()count(100000000)end_time = time.time()print("单进程执行时间:", end_time - start_time)  # 单进程执行时间: 4.279423713684082# 多进程执行start_time = time.time()process1 = multiprocessing.Process(target=count, args=(50000000,))process2 = multiprocessing.Process(target=count, args=(50000000,))process1.start()process2.start()process1.join()process2.join()end_time = time.time()print("多进程执行时间:", end_time - start_time)  # 多进程执行时间: 2.2506167888641357if __name__ == '__main__':main1()

协程实验(该实验中,多协程并不占优,这是因为协程的主要优势在于能够高效地处理I/O密集型任务,如网络请求、文件读写。):

import asyncio
import timeasync def count(n):while n > 0:n -= 1async def main():task1 = asyncio.create_task(count(50000000))task2 = asyncio.create_task(count(50000000))await asyncio.gather(task1, task2)# 单协程执行
start_time = time.time()
asyncio.run(count(100000000))
end_time = time.time()
print("单协程执行时间:", end_time - start_time)# 多协程执行
start_time = time.time()
asyncio.run(main())
end_time = time.time()
print("多协程执行时间:", end_time - start_time)"""
单协程执行时间: 4.209939241409302
多协程执行时间: 4.172176122665405
"""

Python守护进程 守护线程

  1. 守护进程:守护进程是一种在后台运行的进程,不受用户交互的影响。守护进程通常用于执行后台任务,如日志记录、监控等。在 Python 中,可以使用 multiprocessing.Process 类的 daemon 属性来创建守护进程。

  2. 守护线程:守护线程是一种在后台运行的线程,当主线程退出时,守护线程会自动退出。守护线程通常用于执行后台任务,如日志记录、监控等。在 Python 中,可以使用 threading.Thread 类的 daemon 属性来创建守护线程。

守护进程实验:

"""
守护进程
但这段代码不适合在windows OS上运行,适合linux
"""
import os
import sys
import timedef daemonize():pid = os.fork()  # 创建一个新的子进程if pid > 0:sys.exit()os.setsid()  # 创建一个新的会话,并将子进程设置为该会话的会话领导者。这将使子进程脱离控制终端,从而实现守护进程的特性之一。os.umask(0)  # 设置子进程的文件创建模式pid = os.fork()if pid > 0:sys.exit()sys.stdout.flush()sys.stderr.flush()with open("/dev/null", "r") as stdin:os.dup2(stdin.fileno(), sys.stdin.fileno())with open("/dev/null", "a") as stdout:os.dup2(stdout.fileno(), sys.stdout.fileno())with open("/dev/null", "a") as stderr:os.dup2(stderr.fileno(), sys.stderr.fileno())def run():while True:print("Daemon is running...")time.sleep(5)if __name__ == "__main__":daemonize()run()

守护线程实验:

import threading
import timedef run():while True:print("Daemon thread is running...")time.sleep(5)if __name__ == "__main__":daemon_thread = threading.Thread(target=run)  # 线程对象daemon_thread.daemon = Truedaemon_thread.start()  # 启动守护线程# 主线程将等待10秒后结束time.sleep(10)print("Main thread is terminating")"""
Daemon thread is running...
Daemon thread is running...
Main thread is terminating
Daemon thread is running...
"""

鸭子模型

        鸭子模型(Duck Typing)是一种编程概念,主要用于动态类型语言(如 Python)。鸭子模型的核心思想是关注对象的行为,而不是关注对象的类型。换句话说,如果一个对象像鸭子一样走路、叫声,那么我们就认为它是鸭子,而不关心它的实际类型。

class Duck:def quack(self):return "Quack!"class Dog:def quack(self):return "Woof!"def make_sound(animal):print(animal.quack())duck = Duck()
dog = Dog()make_sound(duck)  # 输出 "Quack!"
make_sound(dog)   # 输出 "Woof!"

runserver运行时启动的两个线程是为什么

在Django的runserver命令下运行时,通常会启动两个线程。这两个线程的主要目的是:

  1. 主线程:这个线程负责处理HTTP请求,接收客户端发来的请求,然后调用相应的视图函数处理请求,最后返回响应给客户端。在这个过程中,主线程会处理URL路由、模板渲染、数据库操作等任务。

  2. 自动重新加载线程(Auto-reloader thread):这个线程主要负责监视项目中的源代码文件。当检测到文件发生更改时,它会自动重新加载项目,使得更改立即生效,无需手动重启服务器。这对于开发过程中的调试和快速迭代非常有帮助

        这样的设计可以使得开发者在开发过程中更加高效,因为当代码发生变化时,服务器会自动重新加载,而无需手动重启。同时,通过将自动重新加载功能放在一个单独的线程中,可以确保主线程始终专注于处理HTTP请求,提高服务器的响应速度。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【话题】感觉和身边其他人有差距怎么办?也许自我调整很重要

每个人能力有限,水平高低不同,我们身在大环境里,虽然在同一个起跑线上,但是时间久了,你会发现,并越来越感觉到和身边其他人有了差距,慢慢的会有一定的落差感,怎么办呢!通…

80. 删除有序数组中的重复项 II (力扣刷题)

删除有序数组中的重复项 II 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空…

java读写properties文件和xml文件,解决中文乱码问题

文章目录 前言一、properties文件1.1properties格式介绍1.2读取项目resource/templates下面properties并处理中文乱码问题1.3读取本地properties并处理中文乱码问题1.4修改properties文件 二、XML文件2.1xml文件格式2.2读取xml文件2.3写xml文件 前言 在开发当中我们经常需要用…

MySQL数据库——多表操作

文章目录 前言多表关系一对一关系一对多/多对一关系多对多关系 外键约束创建外键约束插入数据删除带有外键约束的表的数据删除外键约束 多表联合查询数据准备交叉连接查询内连接查询外连接查询左外连接查询右外连接查询满外连接查询 子查询子查询关键字ALL 关键字ANY 和 SOME 关…

Java中各种数据类型占字节数

Java数据类型占用字节数简介 Java是广泛应用于大型企业系统的一种面向对象编程语言,它被广泛应用于多种物联网应用、移动应用开发,以及网站后台的开发中。在Java语言中,数据类型对于变量的定义起到了至关重要的作用,这些数据类型…

Nacos 抽取公共配置

文章目录 创建一个公共配置文件其他配置文件引用springboot配置文件 创建一个公共配置文件 其他配置文件引用 ${变量} springboot配置文件 spring:cloud:nacos:discovery:server-addr: current.ip:8848namespace: word_register_proconfig:server-addr: current.ip:8848auto-r…

大模型时代下,算法工程师该何去何从?

目录 一、大模型时代的罪与罚1.1、快速演进的大模型技术1.2、模型表现出的惊人创造力1.3、大模型AI对算法工程师的威胁性 二、算法工程师的破与发2.1、破——大模型时代给算法工程师带来的新机遇2.2、发——算法工程师如何适应大模型时代的变革 三、大模型时代下人才发展洞察 大…

spring.config.location 手动指定配置文件文件

–spring.config.locationD:\javaproject\bangsun\ds-admin\ds-oper-mgr\src\main\resources\application.yml

IOCP简单了解

1.IOCP是什么 IOCP是Input/Output Completion Ports的简称,中文翻译为完成端口,完成是应用程序向系统发起一个IO操作,系统会在操作结束后,将IO操作完成结果通知应用程序,端口指的是机制 2.重叠IO(Overlappe…

代码调试2:coco数据集生成深度图

代码调试:coco数据集生成深度图 作者:安静到无声 个人主页 问题1:图片存在异常,跳过不处理 在获取深度图的时候,直接执代码,会产生以下错误:RuntimeError和ValueError。 因此我重新修改了代码,如果出现以下两种错误,则执行下一次循环,代码如下: 修改之后代码可以…

iceberg对比hive优势

1.事务性 从事务性上来说,iceberg具有更高的数据质量。 因为iceberg本质是一种table format,屏蔽了底层的存储细节,写入数据时候需要严格按照schema写入。而hive可以先写入底层数据,然后使用load partition的方式来加载分区。这样…

二叉树的相关题目

目录 1、根据二叉树创建字符串 2、二叉树的层序遍历 3、二叉树的最近公共祖先 4、搜索二叉树与双向链表 5、从前序与中序遍历序列构造二叉树 6、 从中序与后序遍历序列构造二叉树 7、二叉树的前序遍历(非递归实现) 8、二叉树的中序遍历&#xff08…

spring — Spring Security 5.7与6.0差异性对比

1. spring security Spring Security 是一个提供身份验证、授权和针对常见攻击保护的框架。 凭借对保护命令式和反应式应用程序的一流支持,它成为基于Spring的标准安全框架。 Spring Security 在最近几个版本中配置的写法都有一些变化,很多常见的方法都…

宇凡微2.4g遥控船开发方案,采用合封芯片

2.4GHz遥控船的开发方案是一个有趣且具有挑战性的项目。这样的遥控船可以通过无线2.4GHz频率进行远程控制,让用户在池塘或湖泊上畅游。以下是一个简要的2.4GHz遥控船开发方案: 基本构想如下 mcu驱动两个小电机,小电机上安装两个螺旋桨&#…

在使用Python爬虫时遇到503 Service Unavailable错误解决办法汇总

在进行Python爬虫的过程中,有时会遇到503 Service Unavailable错误,这意味着所请求的服务不可用,无法获取所需的数据。为了解决这个常见的问题,本文将提供一些解决办法,希望能提供实战价值,让爬虫任务顺利完…

C++、Java、JavaScript和python几个语句的对比介绍

C、Java、JavaScript和python几个语句的对比介绍 C、Java、JavaScript和python语言的for语句 C、Java和JavaScript的for语句的语法类似如下: for (初始条件; 循环条件; 循环后操作) { // 循环体代码 } 初始条件是在进入循环之前执行的语句,初始化循环…

Docker中gitlab以及gitlab-runner的安装与使用

1、本文主要讲述如何使用Docker安装gitlab以及gitlab-runner,并且会讲述gitlab-runner如何使用 2、gitlab部分不需要修改过多的配置即可使用,本文未讲述https配置,如有需求,可自行百度 3、Docker如何安装可以自行百度 一、Docker安…

【尚硅谷】第02章:随堂复习与企业真题(变量与运算符)

来源:尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备) 基本都是宋老师发的资料里面的内容,只不过补充几个资料里没直接给出答案的问题的答案。 不想安装markdown笔记的app所以干脆在这里发一遍。 第02章:随堂复习…

轻量化YOLOv5改进 | 结合repghost结构冲参数化网络,实现轻量化和加速推理,

RepGhost: A Hardware-Efficient Ghost Module via Re-parameterization 论文总结本文改进repghost 核心代码测试参数量和计算量🔥🔥🔥 “引入RepGhostNet以加速CNN网络推理” “网络宽度的自定义调整:无缝嵌入YOLOv5” “通过结构重参数化优化网络性能” “实现高效和…

【JVM】(二)深入理解Java类加载机制与双亲委派模型

文章目录 前言一、类加载过程1.1 加载(Loading)1.2 验证(Verification)1.3 准备(Preparation)1.4 解析(Resolution)1.5 初始化(Initialization) 二、双亲委派…