并发编程 Process 互斥锁
进程理论
程序与进程的区别
'''
程序不是存在硬盘上的代码,相对来说是静态的
进程表示程序在执行的过程,是动态的
'''
进程的调度
先来先服务调度算法
'''对长作业有利,对短作业无益'''
短作业优先调度算法
'''对短作业有利,长作业无益'''
两对重要的概念
同步和异步
'''描述的是任务的提交方式'''
同步:任务提交之后,原地等待任务的返回结果,等待过程中不做任何事情程序表面上表现出来的感觉就是卡住了
异步:任务提交之后,不原地等待任务返回的结果,直接去做其他事情
事后,任务的返回结果会有一个任务回调机制自动处理
阻塞和非阻塞
'''描述的是程序的运行状态'''
阻塞:阻塞态
非阻塞:就绪态、运行态
上述概念的组合:最高效的一种组合就是异步非阻塞
开启进程的方式
from multiprocessing import Process
import time
def task(name):
print('%s is running' % name)
time.sleep(3)
print('%s is over'%name)
if __name__ == '__main__':
# 1、创建一个对象 target=>要执行的任务
p = Process(target=task,args=('卡卡西里',))
# 容器类型哪怕里面只有一个元素 建议要用逗号隔开
# 2 开启进程
p.start() # 告诉系统帮你创建一个进程 异步
print('主进程')
总结
'''创建进程就是在内存中申请一块内存空间将需要运行的代码丢进去
一个进程对应在内存中就是一块独立的内存空间
多个进程对应在内存中就是多块独立的内存空间
进程与进程之间默认情况下是无法直接交互的,想要交互借助于第三方工具、模块
'''
join方法
jion 是让其他主进程等待子进程代码运行结束之后,再继续运行。不影响其他子进程的执行
from multiprocessing import Process
import time
def task(name):
print('%s is running' % name)
time.sleep(3)
print('%s is over' % name)
if __name__ == '__main__':
p1 = Process(target=task, args=('卡卡西里1',))
p2 = Process(target=task, args=('卡卡西里2',))
p3 = Process(target=task, args=('卡卡西里3',))
start = time.time()
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print('主进程',time.time()-start)
'''输出结果
卡卡西里2 is running
卡卡西里1 is running
卡卡西里3 is running
卡卡西里2 is over
卡卡西里1 is over
卡卡西里3 is over
主进程 3.0681638717651367
'''
# for 循环 开启进程 join
from multiprocessing import Process
import time
def task(name, n):
print('%s is running' % name)
time.sleep(n)
print('%s is over' % name)
if __name__ == '__main__':
p_list = []
start = time.time()
for i in range(1,4):
p = Process(target=task, args=('进程%s' % i, i))
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('主进程', time.time() - start)
Process参数
Process的父类里面的属性要传以下参数
'''group=None, target=None, name=None, args=(), kwargs={},
*, daemon=None'''
# target表示的是需要执行的任务,或函数
# name表示的是进程的名字 不传入的话,默认名字是Process-1 后面依次递增
# 也可以传值进行修改
p1 = Process(target=task,name='kakaxili_1' args=('卡卡西里1',))
# args 传入的是元组,传的是任务函数需要的参数 按位置传入
# kwargs 闯入的是字典,传的是任务函数需要的参数,关键字传入
Process类方法
p.start() 开启进程
p.join() jion 是让其他主进程等待子进程代码运行结束之后,再继续运行。不影响其他子进程的执行
p.run() 没有开启子进程,而是把它当作一个进程执行了,相当于串行了
p.termainate() 终止该进程,但是需要时间
p.is_alive() 判断进程是否存活,存活返回True,否则返回False
Process属性
p.pid p进程的id 在主进程中查看的
p.name p进程的进程名称
p.daemon = True daemon默认传入的是False 设为True设置守护进程,主进程如果运行结束,子进程也跟着结束,但是必须放在start之前
获取进程ID的方法
import os
def func():
print(os.getpid()) # 获取当前进程的id
print(os.getppid()) # 获取父进程的id
互斥锁
在python的多线程和多进程中,当我们需要对多线程或多进程的共享资源或对象进行修改操作时,往往会出现因cpu随机调度而导致结果和我们预期不一致的问题,这时就需要对线程或者进程加锁,以保证一个线程或进程在对共享对象进行修改时,其他的线程或进程无法访问这个对象,直至获取锁的线程的操作执行完毕后释放锁。所以,锁在多线程和多进程中起到一个同步的作用,以保护每个线程和进程必要操作的完整执行。
import multiprocessing
import os
import time
from multiprocessing import Process, Lock
def task(i, lock):
lock.acquire() # 获得锁
print('%s号进程,ID:%s 开始执行' % (i, os.getpid()))
time.sleep(2)
print('%s号进程,ID:%s 执行结束' % (i, os.getpid()))
lock.release() # 释放锁
if __name__ == '__main__':
# 实例化得到一把锁
multiprocessing.set_start_method('fork') # mac 解决办法
lock = Lock()
for i in range(1, 5):
p = Process(target=task, args=(i, lock))
p.start()
学习Python3 互斥锁遇到的mac系统遇到的错误 FileNotFoundError: [Errno 2] No such file or directory
mac系统
python3.4更新后,默认用“spawn”,开启进程,我们要主动指定为“fork”
spawn:使用此方式启动的进程,只会执行和 target 参数或者 run() 方法相关的代码。Windows 平台只能使用此方法,事实上该平台默认使用的也是该启动方式。相比其他两种方式,此方式启动进程的效率最低。
fork:使用此方式启动的进程,基本等同于主进程(即主进程拥有的资源,该子进程全都有)。因此,该子进程会从创建位置起,和主进程一样执行程序中的代码。注意,此启动方式仅适用于 UNIX 平台,os.fork() 创建的进程就是采用此方式启动的。
forserver:使用此方式,程序将会启动一个服务器进程。即当程序每次请求启动新进程时,父进程都会连接到该服务器进程,请求由服务器进程来创建新进程。通过这种方式启动的进程不需要从父进程继承资源。注意,此启动方式只在 UNIX 平台上有效。
在实例化锁之前添加
multiprocessing.set_start_method('fork')
并发编程 Process 互斥锁的更多相关文章
- python 并发编程 多进程 互斥锁 目录
python 并发编程 多进程 互斥锁 模拟抢票 互斥锁与join区别
- python 并发编程 多进程 互斥锁与join区别
互斥锁与join 互斥锁和join都可以把并发变成串行 以下代码是用join实现串行 from multiprocessing import Process import time import js ...
- python 并发编程 多进程 互斥锁
运行多进程 每个子进程的内存空间是互相隔离的 进程之间数据不能共享的 一 互斥锁 但是进程之间都是运行在一个操作系统上,进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终 ...
- c++并发编程之互斥锁(mutex)的使用方法
1. 多个线程访问同一资源时,为了保证数据的一致性,最简单的方式就是使用 mutex(互斥锁). 引用 cppreference 的介绍: The mutex class is a synchroni ...
- python 并发编程 多线程 互斥锁
互斥锁 并行变成串行,牺牲效率 保证数据安全,实现局部串行 保护不同的数据,应该加不同的锁 现在一个进程 可以有多个线程 所有线程都共享进程的地址空间 实现数据共享 共享带来问题就会出现竞争 竞争就会 ...
- C++ 并发编程之互斥锁和条件变量的性能比较
介绍 本文以最简单生产者消费者模型,通过运行程序,观察该进程的cpu使用率,来对比使用互斥锁 和 互斥锁+条件变量的性能比较. 本例子的生产者消费者模型,1个生产者,5个消费者. 生产者线程往队列里放 ...
- Java并发编程:Concurrent锁机制解析
Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...
- Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型
一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...
- 并发编程: GIL锁、GIL与互斥锁区别、进程池与线程池的区别
一.GIL 二.关于GIL性能的讨论 三.计算密集测试 四.IO密集测试 五.GIL与互斥锁 六.TCP客户端 七.进程池 八.进程什么时候算是空闲 九.线程池 一.GIL GIL Global In ...
随机推荐
- Acunetix临时扫描是不够的
Web漏洞扫描程序通常被视为即席工具.最初,所有漏洞扫描程序都是这种工具,并且当前的开源Web应用程序安全解决方案仍遵循该模型.但是,随着Web技术的复杂性和可用性的大幅增加,临时模型已经过时,无法满 ...
- DIY一个智能开关kwswitch
源码地址:https://gitee.com/kerwincui/kwswitch 平台简介 该智能开关平台包括服务端.硬件端.PC端和安卓端.硬件使用ESP8266模块,成本相对较低,可以发挥想象力 ...
- final修饰符(3)-基本类型变量和引用类型变量的区别
final修饰基本类型变量 当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变 final修饰引用类型变量 当使用final修饰引用类型变量时,它保存的仅仅是一 ...
- ZYNQ Linux 移植:包含petalinux移植和手动移植debian9
参考: https://electronut.in/workflow-for-using-linux-on-xilinx-zynq/ https://blog.csdn.net/m0_37545528 ...
- 【洛谷1434 [SHOI2002]滑雪】记忆化搜索
AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...
- jmeter测试流程整理
背景 整理jmeter脚本编写流程,注意事项,常用组件,常见问题. 参看链接:https://www.cnblogs.com/pwj2lgx/p/10282422.html 参看:processOn思 ...
- Python基础之创建文件夹与删除文件夹。
参考链接:https://blog.csdn.net/weixin_43826242/article/details/87101436 创建目录结构 # 创建文件目录结构 def create_fol ...
- C++ 定义默认值void locals_index(int reg, int offset = 1);
看jvm源码的时候怎么也看不懂,来回看了几次了就是关于iload 6 指令的解析 def(Bytecodes::_lload , ubcp|____|____|____, vtos, ltos, ll ...
- Laravel Ignition 2.5.1 代码执行漏洞(CVE-2021-3129)
影响范围 Laravel 框架 < 8.4.3 facade ignition 组件 < 2.5.2 poc git clone https://github.com/simonlee-h ...
- anyRTC Web SDK 实现音视频呼叫功能
前言 大家好,今天小编带给大家一个基于 anyRTC Web SDK 实现音视频呼叫的功能(本项目采用vue开发). 前提条件 在开始写代码之前还需要做一些准备工作,如果你之前没有使用过 anyRTC ...