Python--进程基础

创建进程

os.fork()

该方法只能在linux和mac os中使用,因为其主要基于系统的fork来实现。window中没有这个方法。

通过os.fork()方法会创建一个子进程,子进程的程序集为该语句下方的所有语句。

 import os​​print("主进程的PID为:" , os.getpid())w = 1pid = os.fork() # 创建子进程print('fork方法的返回值为: ', pid)if pid == 0:print(f'子进程PID: {os.getpid()}, 主进程PID: {os.getppid()}, 子进程中w: {w}')else:print(f'主进程PID: {os.getpid()}, 主进程PID: {os.getppid()}, 子进程中w: {w}')

multiprocessing(target为函数)

通过multiprocessing模块中的Process类创建一个进程实例对象,并通过其start方法启动该进程。

进程中的程序集为Process类的target参数,可以是一个函数也可以是一个方法。

需要注意的是windows系统中创建进程的过程需要放在if __name__== "__main__"代码块中,因为其实现数据集的复制时,是通过import语句实现。

而在Linux和MacOS系统下则不需要,因为他们原生支持fork方法。

 import multiprocessingimport osimport time​def task():for i in range(3):print("wating... 当前pid为 : ", os.getpid(), "父进程为: ", os.getppid())time.sleep(1)​​​if __name__ == "__main__":print('主进程pid:', os.getpid())​process = multiprocessing.Process(target=task)process.start()

multiprocessing(taget为方法)

创建Process实例对象的target参数,不仅可以是函数名,还可以是类的方法名。

  • 如果需要往target中传入参数,可以通过args和kwargs两个参数进行相应的传参
 import multiprocessingimport time​class Tasks():def task1(self):time.sleep(1)print('task1')​def task2(self):time.sleep(1)print('task2')​if __name__ == "__main__":t = Tasks()process1 = multiprocessing.Process(target=t.task1)process1.start()​process2 = multiprocessing.Process(target=t.task2)process2.start()

继承Process类

通过继承multiprocessing.Process类,并重写其中的run方法。

  • 必须要重写run方法,Process子类的实例对象的run方法,就是进程执行的程序
 import timefrom multiprocessing import Process​​class MyProcess(Process):def __init__(self, i):super().__init__()self.name = str(i)​def run(self):time.sleep(2)print(f'子进程-{self.name}')​​if __name__ == '__main__':for i in range(5):p = MyProcess(i)p.start()​print('主进程')

进程阻塞

目前系统一般都是多核的,当处理多任务时,一般都以并发或并行的方式处理多任务。所以系统一般以异步的方式处理多进程。

Process的实例方法中,通过join方法表示进程阻塞时,主将处于等待状态,并不会处理其他进程。

单进程阻塞

针对每个进程开启后立马启用join方法,这种方法效率低下。使得系统的处理方式编程同步阻塞,使得主进程依次处理子进程。

 import timefrom multiprocessing import Process​def eat():time.sleep(2)print('eat')​def drink():time.sleep(2)print('drink')​if __name__ == '__main__':process1 = Process(target=eat)process1.start()process1.join()​process2 = Process(target=drink)process2.start()process2.join()​​print('主进程')

多进程阻塞

先利用start方法将多个进程同时创建并启动,然后在创建完成后统一阻塞进程。

  • 统一创建进程,并让其统一运行
  • 统一等待进程结束,避免每个进程都等一段时间
 import timefrom multiprocessing import Process​def eat():time.sleep(2)print('eat')​def drink():time.sleep(2)print('drink')​​​if __name__ == '__main__':process1 = Process(target=eat)process1.start()​process2 = Process(target=drink)process2.start()​for p in [process1, process2]:p.join()​print('主进程')

进程锁

当多进程编辑同一文件或数据时,往往会导致数据不一致问题,针对这种情况,需要在进程中对处理文件或数据的代码前后进行加锁和解锁操作。

如果没有锁,会导致数据的不一致

 import time, jsonfrom multiprocessing import Process​​def read_ticket(user):with open('ticket.txt') as f:num = json.load(f)['ticket']time.sleep(1)print(f'User {user}: 当前剩余{num}张票')return num​​def order_ticket(user, num):time.sleep(1)num -= 1with open('ticket.txt', 'w') as f:json.dump({'ticket': num}, f)print(f'User {user}: 购票成功')​​def ticket(user):num = read_ticket(user)if num > 0:order_ticket(user, num)else:print(f'User {user}: 购票失败')​​if __name__ == '__main__':queue = []for i in range(5):p = Process(target=ticket, args=(i,))p.start()queue.append(p)for q in queue:q.join()​print('运行结束')

加锁/解锁

在编辑数据的之前通过acquire方法加锁,当数据编辑完成后,通过release方法解锁。

  • 在主进程中创建一个锁对象
  • 然后在每个修改共同数据的进程中传入已经创建的锁对象
  • 在修改数据的代码前后分别加锁和解锁
 """@Time: 2024/6/28 20:18@Author: 'Ethan'@Email: ethanzhou4406@outlook.com@File: 1. 同步阻塞.py@Project: python@Feature:"""import time, jsonfrom multiprocessing import Process, Lock​​def read_ticket(user):with open('ticket.txt') as f:num = json.load(f)['ticket']time.sleep(0.1)print(f'User {user}: 当前剩余{num}张票')​​def order_ticket(user):time.sleep(0.1)with open('ticket.txt') as f:num = json.load(f)['ticket']if num > 0:with open('ticket.txt', 'w') as f:num -= 1json.dump({'ticket': num}, f)print(f'User {user}: 购票成功')else:print(f'User {user}: 购票失败')​​def ticket(user,lock):read_ticket(user)lock.acquire()order_ticket(user)lock.release()​​if __name__ == '__main__':lock = Lock()queue = []for i in range(5):p = Process(target=ticket, args=(i, lock))p.start()queue.append(p)for q in queue:q.join()​print('运行结束')​

锁的上下文管理器

如果在代码加锁后,解锁前,代码出现了异常就会导致进程没有来得及解锁,而导致死锁现象。通过锁的上下文管理器语法,可以有效避免这种情况的发生。

 import time, jsonfrom multiprocessing import Process, Lock​​def read_ticket(user):with open('ticket.txt') as f:num = json.load(f)['ticket']time.sleep(0.1)print(f'User {user}: 当前剩余{num}张票')​​def order_ticket(user):time.sleep(0.1)with open('ticket.txt') as f:num = json.load(f)['ticket']if num > 0:with open('ticket.txt', 'w') as f:num -= 1json.dump({'ticket': num}, f)print(f'User {user}: 购票成功')else:print(f'User {user}: 购票失败')​​def ticket(user,lock):read_ticket(user)with lock:order_ticket(user)​​if __name__ == '__main__':lock = Lock()queue = []for i in range(5):p = Process(target=ticket, args=(i, lock))p.start()queue.append(p)for q in queue:q.join()​print('运行结束')​

进程间通信

进程之间可以进行通信,主要是通过各个进程之中传入一个公共的沟通工具,所有的进程都通过这个工具进行沟通。multiprocessing中提供了两种进程间沟通的工具QueuePipe

Queue方式

Queue是基于文件传输的socket通信方式,并且它是带锁机制的。它的数据主要的特点是先进先出,后进后出。

当一个对象被放入一个队列中时,这个对象首先会被一个后台线程用pickle序列化,并将序列化后的数据通过一个底层管道的管道传递给队列中。

主要使用如下方法:

  • qsize(): 返回队列的大致的长度。返回的值由于多线程或多进程的上下文而变得不可靠
  • empty(): 队列为空返回True,否则返回False。返回的值由于多线程或多进程的上下文而变得不可靠
  • full(): 队列满了返回True,否则返回False。返回的值由于多线程或多进程的上下文而变得不可靠
  • put(obj[, block[, timeout]]): 将obj放入队列。
    • 如果block为True(默认值)而且timeout是None(默认值),将会阻塞当前进程,直到有空的缓冲槽。
    • 如果timeout是正数,将会阻塞了最多timeout秒之后还是没有可用的缓冲槽时抛出queue.Full异常
    • 反之block为False,仅当有可用缓冲槽时才放入对象,否则抛出queue.Full异常(这种情况下timeout参数会被忽略)

  • get([block[, timeout]]): 从队列中取出并返回对象。如果可选参数block是True而且timeout是None,将会阻塞当前进程,直到队列中出现可用对象。如果timeout是正数,将会阻塞了最多timeout秒之后还是没有可用的对象时抛出queue.Empty异常。
    • 反之,block是False时,仅当有可用对象能够取出时返回,否则抛出queue.Empty异常(这种情况下timeout参数会被忽略)

 import time, jsonfrom multiprocessing import Process, Queue​​def task(i, queue: Queue):time.sleep(1)queue.put(i)print(f'task {i}, 入列')​​if __name__ == '__main__':queue = Queue()process_queue = []for i in range(5):p = Process(target=task, args=(i, queue))p.start()process_queue.append(p)for p in process_queue:p.join()​for i in range(5):print(f'主进程中消费队列内容{queue.get()}')​print('运行结束')​

Pipe方式

Pipe方式是进程之间通信的另一种方式和Queue不同之处在于,它不带锁,且信息顺序无法得到保障。

主要的使用方法:

  • send(obj): 将一个对象发送到链接的另一端,可以用recv()读取,发送的对象必须是可序列化的,多大的对象(接近32MiB)可能引发ValueError异常
  • recv(): 返回一个由另一端使用send()发送的对象,该方法会一直阻塞直到接收到对象。如果对端关闭了链接或者没有东西可接收,将抛出EOFError异常
 import timefrom multiprocessing import Process, Pipefrom multiprocessing.connection import Connection​​def task(pipe:Connection):print('子进程往管道里加了内容')time.sleep(1)pipe.send("子进程往管道中加了点东西")​​if __name__ == '__main__':pipe1, pipe2 = Pipe()p = Process(target=task, args=(pipe1,))p.start()p.join()print('主进程中获取管道内的内容为:', pipe2.recv())print('运行结束')

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

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

相关文章

Python pdfkit wkhtmltopdf html转换pdf 黑体字体乱码

wkhtmltopdf 黑体在html转换pdf时&#xff0c;黑体乱码&#xff0c;分析可能wkhtmltopdf对黑体字体不太兼容&#xff1b; 1.html内容如下 <html> <head> <meta http-equiv"content-type" content"text/html;charsetutf-8"> </head&…

DreamView数据流

DreamView数据流 查看DV中界面启动dag&#xff0c;/apollo/modules/dreamview_plus/conf/hmi_modes/pnc.pb.txt可以看到点击界面的planning按钮&#xff0c;后台其实启动的是/apollo/modules/planning/planning_component/dag/planning.dag和/apollo/modules/external_command…

Oracle连接mysql

oracle使用的11g&#xff0c;在一台windows服务器&#xff1b;mysql使用的是5.7版本&#xff0c;在另一台windows服务器&#xff0c;这两个服务器之间的网络是互通的。做BI时&#xff0c;要获取不同数据源的数据&#xff0c;这些数据源可能是Oracle&#xff0c;也可能是sqlserv…

springboot基础入门2(profile应用)

Profile应用 一、何为Profile二、profile配置方式1.多profile文件方式2.yml多文档方式 三、加载顺序1. file:./config/: 当前项目下的/config目录下2. file:./ &#xff1a;当前项目的根目录3. classpath:/config/:classpath的/config目录4. classpath:/ : classpath的根目录 四…

Redis 集群模式

一、集群模式概述 Redis 中哨兵模式虽然提高了系统的可用性&#xff0c;但是真正存储数据的还是主节点和从节点&#xff0c;并且每个节点都存储了全量的数据&#xff0c;此时&#xff0c;如果数据量过大&#xff0c;接近或超出了 主节点 / 从节点机器的物理内存&#xff0c;就…

个人网站制作 Part 28 添加用户活动跟踪功能 | Web开发项目添加页面缓存

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加用户活动跟踪功能&#x1f528;使用分析工具&#x1f527;步骤 1: 选择分析工具&#x1f527;步骤 2: 注册Google Analytics账户&#x1f527;步骤 3: 获取Analytics…

Java面试题--JVM大厂篇之深入了解G1 GC:高并发、响应时间敏感应用的最佳选择

引言&#xff1a; 在现代Java应用的性能优化中&#xff0c;垃圾回收器&#xff08;GC&#xff09;的选择至关重要。对于高并发、响应时间敏感的应用而言&#xff0c;G1 GC&#xff08;Garbage-First Garbage Collector&#xff09;无疑是一个强大的工具。本文将深入探讨G1 GC适…

李一桐遭遇蜈蚣惊魂

李一桐遭遇“蜈蚣惊魂”&#xff01;刘宇宁展现真男人本色在娱乐圈的幕后&#xff0c;总有一些心跳加速的惊险。近日&#xff0c;李一桐在拍戏时遭遇了一场“蜈蚣惊魂”&#xff0c;让无数粉丝和网友为她捏了一把冷汗。而在这场惊险的遭遇中&#xff0c;刘宇宁展现出了真男人的…

ActiveMq工具之管理页面说明

文章目录 安装ActiveMQ一: 访问管理页面二: 进入管理页面&#xff0c;主页三: Queues页说明四: Topics页说明五: Subscribers页说明 安装ActiveMQ wget https://archive.apache.org/dist//activemq/5.13.3/apache-activemq-5.13.3-bin.tar.gz wget https://mirrors.huaweiclou…

为什么越来越多的企业选择外包?赋能企业未来

软件开发过程包括设计需求、设计方案、产品研发、产品交付、后期维护&#xff0c;许多企业并沒有软件开发的专业能力与工作经验&#xff0c;将软件开发工作进行外包是比较节约成本的&#xff0c;企业能少走不少弯路。 YesPMP平台&#xff08;一站式软件外包、项目外包服务-YesP…

UWA Pipeline 2.6.1版本更新

UWA Pipeline是专为游戏开发团队设计的本地协作平台&#xff0c;旨在帮助团队建立专业的DevOps研发交付流水线。本平台提供了可视化的CI/CD操作界面&#xff0c;高可用的自动化测试和无缝集成的UWA性能保障服务等核心功能。 在最新的Pipeline更新中&#xff0c;UWA引入了参数配…

protobufjs解析proto消息出错RangeError: index out of range: 2499 + 10 > 2499解决办法

使用websocket通讯传输protobuf消息的时候&#xff0c;decode的时候出错了&#xff1a; RangeError: index out of range: 2499 10 > 2499 Error: invalid wire type 4 at offset 1986 出现这种错误的时候&#xff0c;99%是因为proto里面的消息类型和服务端发送的消息类型不…

vue表头字段添加鼠标悬浮提示

<el-table-column prop"jfScore" align"center" min-width"100px"><template slot"header" slot-scope"scope"><div><span>信用积分</span><el-tooltip:aa"scope"class"it…

关于windows,wifi图标显示不了的解决方法

解决方法一&#xff08;解决了我的问题的方法&#xff09;&#xff1a; winr -->输入 regedit 打开注册表 --> 删除HKEY-CLASSES_ROOT\CLSID\{3d09c1ca-2bcc-40b7-b9bb-3f3ec143a87b} CLSID在下面仔细找&#xff0c;然后找到09开头那个删掉重启就可以了&#xff0c;可能…

CAS服务端部署

部署CAS Cas服务端其实就是一个war包。 在资源\cas\source\cas-server-4.0.0-release\cas-server-4.0.0\modules目录下cas-server-webapp-4.0.0.war 将其改名为cas.war放入tomcat目录下的webapps下。启动tomcat自动解压war包。浏览器输入 登录页面 http://localhost:8080/ca…

20240701 每日AI必读资讯

&#x1f3eb;AI真炼丹&#xff1a;整整14天&#xff0c;无需人类参与 - 英矽智能推出全球首个AI参与决策的生物学实验室&#xff0c;实现了14天内完成靶点发现和验证的全自动化闭环实验。 - 该实验室由PandaOmics平台驱动&#xff0c;集成多种预测模型和海量数据&#xff0…

【Python】从基础到进阶(二):了解Python语言基础以及数据类型转换、基础输入输出

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、基本数据类型转换1. 隐式转换2. 显式转换 三、基本输入输出1. 输入&#xff08;input&#xff09;2. 输出&#xff08;print&#xff09;3. 案例&#xff1a;输入姓名、年龄、身高以及体重&#xff0c;计算BMI指…

DM表级触发器

可以理解为行变动级 触发体中写逻辑 这是表修改时调用存储过程 感谢大哥分享: https://blog.csdn.net/WuLex/article/details/83181449 感谢大哥分享: https://blog.csdn.net/ChennyWJS/article/details/131913198

湘潭大学软件工程信息与网络安全复习笔记最后一篇

文章目录 复习建议分数占比流密码A5/1RC4 分组密码DESAES 复习建议 现在笔者复习算是收尾了&#xff0c;现在也是考前的最后一天了&#xff0c;走了不少弯路&#xff0c;但是可能也是必不可少的&#xff0c;复习建议是硬着头皮把这份文件看一遍&#xff0c;不理解的地方找英文…

如何使用sr2t将你的安全扫描报告转换为表格格式

关于sr2t sr2t是一款针对安全扫描报告的格式转换工具&#xff0c;全称为“Scanning reports to tabular”&#xff0c;该工具可以获取扫描工具的输出文件&#xff0c;并将文件数据转换为表格格式&#xff0c;例如CSV、XLSX或文本表格等&#xff0c;能够为广大研究人员提供一个…