(并发编程)进程 (multiprocessing--Process实现进程并发)
并发的本质:切换+保持状态
一、同一个程序执行多次是多个进程
每一个进程有一个PID
import os
os.getppid() #父的pid (pycharm.exe)#cmd 中 pyhon 路径 父的pid(cmd.exe)
os.getpid() #自己的pid (python.exe)
windows (createprocess) 创建子进程时子辈除了拷贝父辈的信息还创建了些自己的东西
unix (fork) 创建子进程时拷贝父辈的信息,子进程的初始状态和父辈一致
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(3)
print('%s is done' %name)
if __name__ == '__main__':
# 在windows系统之上,开启子进程的操作一定要放到这下面
# Process(target=task,kwargs={'name':'egon'}) #两种传参方式皆可
p=Process(target=task,args=('egon',)) #两种传参方式皆可
p.start() # 向操作系统发送请求,操作系统会申请内存空间,把父进程的数据拷贝给子进程,作为子进程的初始状
print('======主')
第二种
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super(MyProcess,self).__init__() #Process在init里面有相应设置,要遗传下来,否则报错
self.name=name
def run(self):
print('%s is running' %self.name)
time.sleep(3)
print('%s is done' %self.name)
if __name__ == '__main__':
p=MyProcess('egon')
p.start() #p.start()调用了类中的run()方法(规定)
print('主')
from multiprocessing import Process
import time
x=1000
def task():
time.sleep(3)
global x
x=0
print('儿子死啦',x)
if __name__ == '__main__':
p=Process(target=task)
p.start()
time.sleep(5)
print(x)
#在子进程中对变量x的修改不影响父进程中x的值
#了解 连续start再连续join 和 连续start,join。。。。
from multiprocessing import Process
import time
x=1000
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__':
start_time=time.time()
p1=Process(target=task,args=(1,))
p2=Process(target=task,args=(2,))
p3=Process(target=task,args=(3,))
p1.start()
p2.start()
p3.start()
p3.join() #3s
p1.join()
p2.join()
print('主',(time.time() - start_time)) #3.01637601852417
from multiprocessing import Process
import time
x=1000
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__':
start_time=time.time()
p_l=[]
for i in range(1,4):
p=Process(target=task,args=(i,))
p_l.append(p)
p.start()
for p in p_l:
p.join()
print('主',(time.time() - start_time)) #3.0141923427581787
from multiprocessing import Process
import time
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__': # 在windows系统之上,开启子进程的操作一定要放到这下面
start_time=time.time()
p1=Process(target=task,args=(1,),name='任务1')
p1daemon=True #再obj发出创建前,将obj变成守护进程,主进程执行完毕后子进程跟着结束
p1.start() #向操作系统发创建子进程请求,父进程无需等待
print(p1.pid)
print(p1.name) #如前面不定义name,默认process-1 etc
p1.terminate() #向操作系统发请求,父进程无需等待
p1.join() #等待该子进程结束(卡住吧),父进程需要等待一点时间
print(p1.is_alive())
print('主') #这里的效果是主进程等儿子死了,再结束
import time,os
def task():
print('self:%s parent:%s' %(os.getpid(),os.getppid()))
time.sleep(3)
if __name__ == '__main__':
p1=Process(target=task,)
p1.start()
print(p1.pid)
print('主',os.getpid())
在unix系统中init是所有进程的爹;创建进程用fork,回收进程(结束进程的残留信息?)用waitpid
僵尸进程(有害:占用pid):子代先于父代终结,其部分信息(pid等)没有从系统中删除,需要父代回收。join中含有回收子代信息的功能。
孤儿进程(无害):父代先于子代终结,子代终结后的部分信息由init代收。
import time,os
def task(n):
print('%s is running' %n)
time.sleep(n)
if __name__ == '__main__':
1=Process(target=task,args=(1,))
p1.start()
p1.join() # join中含有回收子代信息的功能(wait)
print('======主',os.getpid())
七、守护进程
from multiprocessing import Process
import time
print('%s is running' % name)
time.sleep(3)
obj = Process(target=task, args=('egon',))
obj.daemon=True #将obj变成守护进程,主进程执行完毕后子进程跟着结束
obj.start() # 发送信号给操作系统
print('主')
强调:必须是lock.acquire()一次,然后 lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()。否者程序停在原地。
抢同一把锁:生成锁对象 必须放在if __name__=='__main__': 下面
互斥锁vs join:
大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序(在多个程序共享一个资源时,为保证有序不乱,需将并发变成串行)
场景: 修改公共数据,如果并发会发出数据错乱,这时就必须串行执行,就要用到互斥锁
区别一:join是按照人为指定的顺序执行,而互斥锁是所以进程平等地竞争,谁先抢到谁执行
区别二:互斥锁可以让一部分代码串行,而join只能将代码整体串行(详见抢票系统)
理解:首先join肯定是一个子进程对象,互斥锁可以加在子进程对象代码任意部位(要释放额)
join人为安排子进程执行顺序,互斥锁是公平竞争。
from multiprocessing import Process,Lock
import time,random
print(id(mutex))
lock.acquire()
# print('task1:名字是egon')
# time.sleep(random.randint(1,3))
# print('task1:性别是male')
time.sleep(random.randint(1,3)) #with mutex: time.sleep(random.randint(1,3))
# print('task1:年龄是18')
lock.release()
lock.acquire()
print('task2:名字是alex')
time.sleep(random.randint(1,3))
print('task2:性别是male')
time.sleep(random.randint(1,3))
print('task2:年龄是78')
lock.release()
lock.acquire()
print('task3:名字是lxx')
time.sleep(random.randint(1,3))
print('task3:性别是female')
time.sleep(random.randint(1,3))
print('task3:年龄是30')
lock.release()
p1=Process(target=task1,args=(mutex,))
p2=Process(target=task2,args=(mutex,))
p3=Process(target=task3,args=(mutex,))
p2.start()
p3.start()
import json
import time
import random
import os
from multiprocessing import Process,Lock
time.sleep(random.randint(1,3))
with open('db.json','r',encoding='utf-8') as f:
dic=json.load(f)
print('%s 剩余票数:%s' %(os.getpid(),dic['count']))
with open('db.json','r',encoding='utf-8') as f:
dic=json.load(f)
if dic['count'] > 0:
dic['count']-=1
time.sleep(random.randint(1,3))
with open('db.json','w',encoding='utf-8') as f:
json.dump(dic,f)
print('%s 购票成功' %os.getpid())
search()
lock.acquire()
get()
lock.release()
for i in range(10):
p=Process(target=task,args=(mutex,)) #这里子进程用的都是主进程这一把锁 id
p.start()
(并发编程)进程 (multiprocessing--Process实现进程并发)的更多相关文章
- Java并发编程的艺术读书笔记(1)-并发编程的挑战
title: Java并发编程的艺术读书笔记(1)-并发编程的挑战 date: 2017-05-03 23:28:45 tags: ['多线程','并发'] categories: 读书笔记 --- ...
- Java并发编程的艺术读书笔记(2)-并发编程模型
title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- [书籍翻译] 《JavaScript并发编程》第七章 抽取并发逻辑
本文是我翻译<JavaScript Concurrency>书籍的第七章 抽取并发逻辑,该书主要以Promises.Generator.Web workers等技术来讲解JavaScrip ...
- java并发编程笔记(九)——多线程并发最佳实践
java并发编程笔记(九)--多线程并发最佳实践 使用本地变量 使用不可变类 最小化锁的作用域范围 使用线程池Executor,而不是直接new Thread执行 宁可使用同步也不要使用线程的wait ...
- 并发编程——多进程——multiprocessing开启进程的方式及其属性(3)
开启进程的两种方式——Process 方式一:函数方法 from multiprocessing import Process import time def task(name): print('% ...
- 03并发编程(多道技术+进程理论+进程join方法)
目录 03 并发编程 03 并发编程
- Java并发编程(一):进程和线程之由来
转自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当 ...
- 并发编程7 管道&事件&信号量&进程池(同步和异步方法)
1,管道 2.事件 3.信号量 4.进程池的介绍&&进程池的map方法&&进程池和多进程的对比 5.进程池的同步方法和异步方法 6.重新解释同步方法和异步方法 7.回调 ...
- 进程 multiprocessing Process join Lock Queue
多道技术 1.空间上的复用 多个程序公用一套计算机硬件 2.时间上的复用 cpu 切换程序+保存程序状态 1.当一个程序遇到IO操作,操作系统会剥夺该程序的cpu执行权限(提高了cpu的利用率,并且不 ...
随机推荐
- luogu P4198 楼房重建——线段树
题目大意: 小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线 ...
- 【洛谷P3586】LOG
题目大意:维护一个集合,支持单点修改.查询小于 X 的数的个数.查询小于 X 的数的和. 题解:学习到了动态开点线段树.对于一棵未经离散化的权值线段树来说,对于静态开点来说,过大的值域会导致不能承受的 ...
- 【洛谷P1248】加工生产调度
题目大意:某工厂收到了n个产品的订单,这n个产品分别在A.B两个车间加工,并且必须先在A车间加工后才可以到B车间加工.某个产品i在A.B两车间加工的时间分别为Ai.Bi.怎样安排这n个产品的加工顺序, ...
- FTP文件乱码和传输模式解释
转: FTP文件乱码和传输模式解释 2017年02月18日 10:50:03 -Hermes- 阅读数:12112更多 所属专栏: 异常解决方案急诊室 版权声明:大侠,在转载时请注明出处,小弟不胜 ...
- #ifndef HeaderName_h #define HeaderName_h #endif 使用详解
想必很多人都看到过头文件中写有:#ifndef HeaderName_h #define HeaderNa ...
- shiro项目从 log4j1X 迁移到 log4j2X
先说一下,shiro依赖的项目不是log4j 而是 SLF4J框架. 我们原来用1X版本的jar包如下: log4j-1.2.17.jar slf4j-api-1.7.22.jar slf4j-log ...
- 20145215《网络对抗》Exp7 网络欺诈技术防范
20145215<网络对抗>Exp7 网络欺诈技术防范 基础问题回答 通常在什么场景下容易受到DNS spoof攻击? 在同一局域网下比较容易受到DNS spoof攻击,攻击者可以冒充域名 ...
- Python中if-else的多种写法
a, b= 1, 2 将a和b两个变量中的最大值赋值给c (1)常规写法 if a>b: c = a else: c = b (2)表达式 c = a if a>b e ...
- SpringBoot @Async 异步处理业务逻辑和发短信逻辑
有个业务场景,业务数据审核通过后需要给用户发短信,发短信过程比较耗时,可能需要几秒甚至十几秒,因此使用异步发短信 使用了注解@Async来实现: 1.SpringApplication启用注解@Ena ...
- 函数和常用模块【day06】:shelve模块(五)
本节内容 1.简述 2.shelve概念 3.shelve模块使用 4.总结 一.简述 之前我们说不管是json也好,还是pickle也好,在python3中只能dump一次和load一次,不能dum ...