day32 process模块用法
昨日作业:
服务端:
服务端: from socket import *
from multiprocessing import Process def server(ip,port):
server = socket(AF_INET, SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind((ip,port))
server.listen(5)
while True:
conn, addr = server.accept()
print(addr)
# communicate(conn)
p = Process(target=communicate, args=(conn,))
p.start()
server.close() def communicate(conn):
while True:
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close() if __name__ == '__main__':
server('127.0.0.1', 8090)
客户端:
from socket import * client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8090)) while True:
msg=input('>>: ').strip()
if not msg:continue client.send(msg.encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8'))
os模块下的进程id:
print(os.getpid(), os.getppid()) # 这里的getpid 是当前进程的id地址
time.sleep(200)
# 得到的结果是(5740,3272)
# 5740是当前的进程的id地址,而后面的3272则是pycharm的id地址,
# 因为程序是在pycharm里面执行的,最终结果是在cmd解释器里面运行
# 每次重新运行进程就是得到一个新的进程,所以,进程id是会有变化
# 同理,pycharm如果重新进入,一样会改变pycharm的id,
上节内容回顾:
1 什么是进程?
进程是一个抽象的概念,进程即正在执行的过程,进程的概念起源于操作系统,
进程的创建,调度管理都归操作系统管
2 操作系统的作用?
1、管理硬件,把复杂丑陋的硬件接口封装成良好的接口给用户使用
2、进程的创建,调度管理都归操作系统管
3 多道技术?
产生背景:针对单核下实现并发
核心:
1、空间上复用(多个进程的内存空间是互相隔离的)
2、时间上复用(复用cpu的时间,)
4 开启进程
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(2)
if __name__ == '__main__': #在windows系统下,开子进程的代码必须写到这一行下面
p=Process(target=task,args=('egon',))
p.start() #只是在给操作系统发了一个信号,让操作系统去开进程(申请内存+拷贝父进程的地址空间)
print('主')
================================================================================================
from multiprocessing import Process
创建进程的类:
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动) 强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 在windows中Process()必须放到# if __name__ == '__main__':下
进程直接的内存空间是隔离的 开启进程的两种方式
#方式一:
# from multiprocessing import Process
# import time
#
# def task(name):
# print('%s is running' %name)
# time.sleep(2)
#
# if __name__ == '__main__': #在windows系统下,开子进程的代码必须写到这一行下面
# p=Process(target=task,args=('egon',))
# p.start() #只是在给操作系统发了一个信号,让操作系统去开进程(申请内存+拷贝父进程的地址空间)
# print('主') ================================================================================================== #方式二:
from multiprocessing import Process
import time class Myprocess(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
time.sleep(3)
print('%s is running' % self.name)
time.sleep(2) if __name__ == '__main__': # 在windows系统下,开子进程的代码必须写到这一行下面
p = Myprocess('egon')
p.start() # p.run()
print('主')
start方法:{
一种是使用Process开启进程
一种是使用Myprocess开启进程}
属性和方法:
我们的join用法是很重要的用法,还有start()也很重要启动子进程,
join用法是为了回收子进程,等待所有的子进程回收后才会去执行父进程,然后结束程序,这样就可以避免掉子进程没有被回收然后沦落为孤儿进程或者僵尸进程的情况。
from multiprocessing import Process
import time,random def piao(name):
print('%s is piaoing' %name)
time.sleep(random.randint(1,3))
print('%s is done' %name) if __name__ == '__main__':
# p1=Process(target=piao,args=('alex',))
# p2=Process(target=piao,args=('wxx',))
# p3=Process(target=piao,args=('yxx',))
#
# p1.start()
# p2.start()
# p3.start()
#
# p3.join() # join(p)
# p1.join() #join(p)
# p2.join() #join(p)
#
# print('主') p1=Process(target=piao,args=('alex',))
p2=Process(target=piao,args=('wxx',))
p3=Process(target=piao,args=('yxx',))
p_l=[p1,p2,p3]
for p in p_l:
p.start() for p in p_l:
p.join() print('主') # import time,os
# print(os.getpid(),os.getppid())
# time.sleep(1000) #python3 test.py --->python.exe #其他属性或方法
from multiprocessing import Process
import time, random
def task():
print('孙子运行了')
time.sleep(3) def piao(name):
print('%s is piaoing' % name)
time.sleep(random.randint(1, 3))
print('%s is done' % name)
p=Process(target=task,)
p.start() if __name__ == '__main__':
p1=Process(target=piao,args=('alex',),name='xxxxxxxx')
p1.start()
# print(p1.name)
# print(p1.pid)
# p1.join()
# p1.terminate()
# print(p1.is_alive())
# p1.join(timeout=1)
print('主')
join用法
from multiprocessing import Process
import time
import random
def piao(name):
print('%s is piaoing' %name)
time.sleep(random.randint(1,3))
print('%s is piao end' %name) p1=Process(target=piao,args=('egon',))
p2=Process(target=piao,args=('alex',))
p3=Process(target=piao,args=('yuanhao',))
p4=Process(target=piao,args=('wupeiqi',)) p1.start()
p2.start()
p3.start()
p4.start() #有的同学会有疑问:既然join是等待进程结束,那么我像下面这样写,进程不就又变成串行的了吗?
#当然不是了,必须明确:p.join()是让谁等?
#很明显p.join()是让主线程等待p的结束,卡住的是主线程而绝非进程p, #详细解析如下:
#进程只要start就会在开始运行了,所以p1-p4.start()时,系统中已经有四个并发的进程了
#而我们p1.join()是在等p1结束,没错p1只要不结束主线程就会一直卡在原地,这也是问题的关键
#join是让主线程等,而p1-p4仍然是并发执行的,p1.join的时候,其余p2,p3,p4仍然在运行,等#p1.join结束,可能p2,p3,p4早已经结束了,这样p2.join,p3.join.p4.join直接通过检测,无需等待
# 所以4个join花费的总时间仍然是耗费时间最长的那个进程运行的时间
p1.join()
p2.join()
p3.join()
p4.join() print('主线程') #上述启动进程与join进程可以简写为
# p_l=[p1,p2,p3,p4]
#
# for p in p_l:
# p.start()
#
# for p in p_l:
# p.join()
当进程中有子进程的时候,会先执行父进程然后再执行子进程, 这样就会出现如下的情况(产生僵尸进程或者孤儿进程,占用内存空间)
进程回收机制,这里有两个概念,孤儿进程(当你的主进程把自己主进程该干的活运行完之后会回来等子进程运行完后回收子进程,但是有一种操作会杀死父进程(如taskkill),你就变成了孤儿进程,没有父进程来回收子进程,但是这里会有类似福利院的机制,就是系统内部的回收机制,当然了回收的会很慢,在被系统内部的回收机制回收之前该子进程都会占用内存。)。僵尸进程(此类进程是没有父进程回收它,也没有福利院机制回收它。代码运行完后cpu会立即被释放出来,但是进程依然存留在内存空间中,内存空间的占用需要被释放掉,正常来说子进程会被父进程回收,如果父进程意外身亡(写代码的过程中不应该出现在子进程被回收之前把父进程写死,但是技术不济就会出现这类问题),就会有系统内部的回收机制来处理它把它回收掉,如果遇到系统内部的回收机制出现故障,那么就没有机制来回收该进程,它就变成了僵尸进程,会一直占用内存,此时就会很危险,内存一直被占用会影响系统运行速度)
进程池:
'''
提交/调用任务的方式有两种:
同步调用:提交/调用一个任务,然后就在原地等着,等到该任务执行完毕拿到结果,再执行下一行代码
异步调用: 提交/调用一个任务,不在原地等着,直接执行下一行代码,结果? ''' # # from multiprocessing import Process,Pool
# from concurrent.futures import ProcessPoolExecutor
# import time,random,os
#
# def piao(name,n):
# print('%s is piaoing %s' %(name,os.getpid()))
# time.sleep(1)
# return n**2
#
# if __name__ == '__main__':
# p=ProcessPoolExecutor(4)
# objs=[]
# start=time.time()
# for i in range(10):
# # res=p.submit(piao,'alex %s' %i,i).result() #同步调用
# # print(res)
# obj=p.submit(piao,'alex %s' %i,i) #异步调用
# objs.append(obj)
#
# for obj in objs:
# print(obj.result())
#
# stop=time.time()
# print(stop-start)
# # 关门+等
# # pool.close()
# # pool.join()
# p.shutdown(wait=True)
# print('主',os.getpid()) # from multiprocessing import Process,Pool
from concurrent.futures import ProcessPoolExecutor
import time, random, os def piao(name, n):
print('%s is piaoing %s' % (name, os.getpid()))
time.sleep(1)
return n ** 2 if __name__ == '__main__':
p = ProcessPoolExecutor(4)
objs = []
start = time.time()
for i in range(10):
# res=p.submit(piao,'alex %s' %i,i).result() #同步调用
# print(res)
obj = p.submit(piao, 'alex %s' % i, i) # 异步调用
objs.append(obj) p.shutdown(wait=True)
print('主', os.getpid())
for obj in objs:
print(obj.result()) stop = time.time()
print(stop - start)
今天的总结,进程的两种开启方式,一种是使用process,定义一个函数,另一种是使用myprocess,定义一个类,类里面必须要有run方法
这两种方法子进程必须要写在(在windows系统里是这样)
if __name__ == '__main__':
有start(开启一个子进程)和join方法(回收一个子进程),
还有就是process属性的一些其他方法和属性,有terminate,删除进程,pid是查看当前进程的ID地址
is_alive,查看当前进程是否是还存在的,
再就是关于进程池的概念,所谓的进程池就是相当于一个小池子,它是为了划分范围的,应用场景就是:
当我们的服务端跟客户端链接的时候,服务端是一个,它要跟多个客户端链接,它不可能同时连接上无上限的客户端,它的系统会崩溃,
但是也不能一次链接一个客户端,这样当然不会崩,但是效率也太低了,所以由于硬件的受限,我们要在有限的硬件条件下实现效率最大化,
那么就需要划定一个范围,在这个范围内我们可以在能承受的范围内实现效率的最大化.这就是我们的进程池的概念,
在进程池的概念中还有同步和异步:
在同步调用中提交一个任务或者调用一个任务的时候,父进程就在原地等待着,等到子进程执行完之后把它回收过来拿到一个结果
然后再执行下一行代码,得到的结果就是所有的进程执行累加的时间,这样的效率会很低,如果我们使用进程池就不会用这种方法,使用进程池就是为了在大量的
数据处理中可以提高效率用的.
而在异步调用中提交一个任务或者调用的时候,父进程不会在原地等着,直接执行下一行代码,然后最后把所有的子进程的结果统一返回
这样的执行效率就更高了,就像昨天学的实现了时间和空间上的复用.这样最后的执行时间就是最长时间的那个进程的时间,而不是所有的进程累加的时间
day32 process模块用法的更多相关文章
- 创建多进程之multiprocess包中的process模块
创建多进程之multiprocess包中的process模块 1.process模块是一个创建进程的模块 Process([group [, target [, name [, args [, kwa ...
- nodejs-Child Process模块
JavaScript 标准参考教程(alpha) 草稿二:Node.js Child Process模块 GitHub TOP Child Process模块 来自<JavaScript 标准参 ...
- Node.js process 模块常用属性和方法
Node.js是常用的Javascript运行环境,本文和大家发分享的主要是Node.js中process 模块的常用属性和方法,希望通过本文的分享,对大家学习Node.js http://www.m ...
- Node.js的process模块
process模块用来与当前进程互动,可以通过全局变量process访问,不必使用require命令加载.它是一个EventEmitter对象的实例. 属性 process对象提供一系列属性,用于返回 ...
- python笔记之常用模块用法分析
python笔记之常用模块用法分析 内置模块(不用import就可以直接使用) 常用内置函数 help(obj) 在线帮助, obj可是任何类型 callable(obj) 查看一个obj是不是可以像 ...
- ansible之二:模块用法
一:ansible远程执行命令 [root@ansible ~]# ansible test -m shell -a "date" >> 2016年 08月 02日 星 ...
- ansible常用模块用法
ansible常用模块用法 2015-07-21 10:25 24458人阅读 评论(1) 收藏 举报 分类: Linux(44) ansible 版权声明:本文为博主原创文章,未经博主允许不得 ...
- 在Python程序中的进程操作,multiprocess.Process模块
在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...
- nodeJS---URL相关模块用法(url和querystring)
nodeJS---URL相关模块用法(url和querystring) 一: URL模块: URL模块用于解析和处理URL的字符串,提供了如下三个方法: 1. parse 2. format 3. r ...
随机推荐
- oracle数据库链路和同义词
Oracle数据库链路的建立和使用 先来一个例子: --创建数据库链路create public database link xaffdblink connect to zdcl identi ...
- swift 实践- 01 -- UItableView的简单使用
import UIKit class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource{ over ...
- 使用JUnit进行类的测试(一)
首先是测试的一些常用标注: @Test:执行测试的方法 @Before & @After : 在 测试的方法 “前” 或者 “后” 被唤醒 -Initialization -Release r ...
- 不想用ssh框架
学过三遍多的样子,没有感悟到特别多的好处. 现在工作都用,想找一个不用这个的工作就不好找.c的话,觉得没有Java面向对象提炼得好. 不是很明白怎么都用,知道自己不想用.里边太多复杂和要背下来的东西, ...
- Confluence 6 针对你的数据库类型确定校验 SQL
不同的数据库通常要求不同的 SQL 校验查询.校验查询通常需要尽可能的简单,这个查询在链接从数据库连接池中取出的时候都会被执行一次. 针对不同的数据库类型,我们推荐先的校验查询 SQL: MySQL ...
- Java的输入语句以及本周对于文件读写的研究
日期:2018.9.20 博客期:010 星期四 ##:今天下午要考试 java(小考)!那么,我就应对相应的方法给出策略吧! 首先是 Java 里的输入语句,我一般是用Scanner类,用这个之前要 ...
- Jmeter 传值对比
${XXX}----------------------->在同一线程内可任务调用变量: vars.put(row,rowNum); ----------------------->var ...
- 论文阅读笔记二十五:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition(SPPNet CVPR2014)
论文源址:https://arxiv.org/abs/1406.4729 tensorflow相关代码:https://github.com/peace195/sppnet 摘要 深度卷积网络需要输入 ...
- 论文阅读笔记四:CTPN: Detecting Text in Natural Image with Connectionist Text Proposal Network(ECCV2016)
前面曾提到过CTPN,这里就学习一下,首先还是老套路,从论文学起吧.这里给出英文原文论文网址供大家阅读:https://arxiv.org/abs/1609.03605. CTPN,以前一直认为缩写一 ...
- Redis的搭建和Redis的集群搭建
1.Redis的官网:https://redis.io/ Redis的测试网站:http://try.redis.io/ 2.参考博客:https://www.cnblogs.com/maf ...