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 ...
随机推荐
- 数据结构HashMap(Android SparseArray 和ArrayMap)
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在.在HashMap中,key-value总是会当做一个整体来处理,系统会根据 ...
- centos7 nginx图片 服务器可以访问ftp用户上传的图片资源的配置
注:本文参考了csdn:JAVA_DIRECTION的<nginx和ftp搭建图片服务器>一文.在实践中其文在centos7中还是存在缺陷性的 一:前提条件:是成功的安装好了ftp服务器和 ...
- js 获取当前的网址
http://www.xcx.cc/index.php/home/index/ind?idf=12321var $cur_url=window.location.href; //获取全部的网址var ...
- (七)STL适配器
1.适配器是稍微修改某些功能,比如三个参数改为两个参数,函数的名称改一下等等,可以出现在容器.迭代器和仿函数中. 2.适配器相当于对某个东西进行封装,例如A是B的适配器,则真正的功能实现是在B中,可以 ...
- SpringBoot的yml配置文件
1.在src\main\resources下创建application.yml配置文件 spring: datasource: driver-class-name: com.mysql.jdbc.Dr ...
- CF939F
好神奇的dp... 首先有一个很简单的思想:设dp[i][j]表示目前到了第i分钟,朝上的面被烤了j分钟的情况下所需的最小交换次数 那么有转移:dp[i][j]=min(dp[i-1][j],dp[i ...
- python+selenium十四:xpath和contains模糊匹配
xpath可以以标签定位,也可以@任意属性: 如:以input标签定位:driver.find_element_by_xpath("//input[@id='kw']") 如:@t ...
- 改变html结构可以实现优先加载
我们通过一个实例来看一下: 本编程题目,完成一个混合布局的编写吧!最终效果如下图: 任务 任务1:完成顶部(top).底部(foot)宽度自适应 任务2:中间分为2两栏,其中,左侧(left)宽度为2 ...
- K8s-Pod控制器
在K8s-Pod文档中我们创建的Pod是非托管的Pod,因为Pod被设计为用后就弃的对象,如果Pod正常关闭,K8s会将该Pod清除,它没有自愈的能力.Pod控制器是用来保持Pod状态的一种对象资 ...
- MS-DOS运行java工程
D:\SourceCode\mailProxy\out\production\examples>java -classpath .;org\roger\stud y\mailClient;D:\ ...