---恢复内容开始---

前情提要:

    一:进程Process 

    1:模块介绍 from multiprocessing import Process

      

from multiprocessing import Process
# print(os.getpid()) #获取本线程id
def fun1():
time.sleep()
print('hello word',os.getpid(),os.getppid())
if __name__ =='__main__':
for i in range(): #通过for 循环开启多个子进程
Process(target=fun1).start() #开启一个新的子进程
time.sleep()
print('hello2,',os.getpid(),os.getppid())
#
# 子进程可以有返回值么?
# 不能有返回值
# 因为子进程函数中的返回值无法传递给父进程,因为内存隔离的问题

    二:join() 阻塞的使用,以及主进程与子进程的关系

      1:p.start() 是非阻塞的模式,

        所以先走主进程

        之后子进程开始

from multiprocessing import Process
import time
def send_emil(n):
time.sleep(0.1)
print('发送邮件%s'%n)
if __name__ == '__main__': for i in range(): #创建10个进程
p =Process(target=send_emil,args=(i,)) #参数target+函数名, args +元祖参数 p.start() #非阻塞的模式 print('所有邮件都发送完了') #先走主进程
>>>>>>>>>>>>>>.

所有邮件都发送完了
发送邮件0
发送邮件3
发送邮件1
发送邮件5
发送邮件6
发送邮件4
发送邮件2
发送邮件7
发送邮件8
发送邮件9

      2:在p.start() 开启进程后面增加p.join() 阻塞(阻塞直至子进程完全走完)

        就会造成变成变行模式

from multiprocessing import Process
import time
def send_emil(n):
time.sleep(0.1)
print('发送邮件%s'%n)
if __name__ == '__main__': for i in range(): #创建10个进程
p =Process(target=send_emil,args=(i,)) #参数target+函数名, args +元祖参数 p.start() #开启一个,
p.join() #阻塞直至子进程结束才停止阻塞 print('所有邮件都发送完了')
>>>>>>>>>>>>>
发送邮件0
发送邮件1
发送邮件2
发送邮件3
发送邮件4
发送邮件5
发送邮件6
发送邮件7
发送邮件8
发送邮件9
所有邮件都发送完了

      3:每一个p.start()生成的句柄放在一个列表中,在循环关闭

from multiprocessing import Process
import time
def send_emil(n):
time.sleep(0.1)
print('发送邮件%s'%n)
if __name__ == '__main__':
p_lis =[]
for i in range(): #创建10个进程
p =Process(target=send_emil,args=(i,)) #参数target+函数名, args +元祖参数
p_lis.append(p)
p.start() #
for p in p_lis:
p.join() #阻塞,直至当前子进程执行完才结束
print('所有邮件都发送完了')
>>>>>>>>>>>>>>>
发送邮件0
发送邮件1
发送邮件2
发送邮件3
发送邮件5
发送邮件6
发送邮件4
发送邮件7
发送邮件8
发送邮件9
所有邮件都发送完了

    三: 进程之间的数据是相互隔离的

from multiprocessing import Process
n =
def fun1():
global n
n = n-
if __name__ == '__main__':
p_lis =[]
for i in range(): #开启10个子进程.然后每个子进程都拿到100 自行减1 不对原100有任何影响
p =Process(target=fun1)
p.start()
p_lis.append(p)
for p in p_lis:
p.join()
print(n) #
>>>>>>>>>>>>

    四:用类的方式开启进程

      1:简单方式

import os
from multiprocessing import Process
class MyProcess(Process): # 定义一个类,继承Process
def __init__(self,arg):
super().__init__() # 加入原来的__init__ 的东西
self.arg =arg
def run(self):
print(os.getpid(),os.getppid()) # 获取进程id ,获取爷进程id #
if __name__ == '__main__':
p =MyProcess() #这个123是给arg 传的
p.start() #开启进程
p.join() #阻塞
print('主进程',os.getpid())
>>>> 主进程

      2: p.terminate()  的用法,

from multiprocessing import Process
import time
class Myprocess(Process):
def __init__(self,a,b):
super().__init__() #原__init__
self.a =a
self.b =b
def run(self):
print('start')
time.sleep(0.5)
print('end',self.a,self.b)
if __name__ == '__main__':
p =Myprocess(,)
p.start()
print(p.is_alive())
time.sleep()
print(p.name,p.pid)
p.terminate() #非阻塞 关闭进程
print(p.is_alive()) #判断进程是不是活着的
time.sleep(0.2)
print(p.is_alive()) #p.terminate 需要响应时间,并不是说关就关,因为是非阻塞模式
>>>>>>>>>>>>>. True
start
Myprocess-
True
False

    五:守护进程,就是在主函数运行的时候附加一个函数并行,去做其他事情

        比如客户端告诉服务器客户端的状况

from multiprocessing import Process
import time
def eye():
while :
print('告诉server 端我活的很好')
time.sleep(0.5)
def mian(): #主函数
print('我想做的是事情')
time.sleep()
print('done')
if __name__ == '__main__':
p =Process(target=eye)
p.daemon =True #将p设置守护进程
p.start() #子进程开始
mian() #主函数开始 , 子进程随着主进程结束而结束
>>>>>>>>>>>>> 我想做的是事情
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
告诉server 端我活的很好
done
from multiprocessing import Process
import time
def fun1():
print('kaishi')
time.sleep()
print('end')
def eye():
while :
print('告诉server 端我活的很好')
time.sleep(0.5)
def mian(): #主函数
print('我想做的是事情')
time.sleep()
print('done')
if __name__ == '__main__': p =Process(target=eye)
p1 =Process(target=fun1) p.daemon =True #将p设置守护进程
p.start() #子进程开始
p1.start()
# p1.join()
mian() #主函数开始 , 子进程随着主进程结束而结束

    六:使用多进程的方式实现socket ,server多并发

import socket
from multiprocessing import Process
def fun1(conn):
while :
conn,send(b'hello')
if __name__ == '__main__':
sk = socket.socket()
sk.bind(('127.0.0.1',))
sk.listen()
while :
conn,addr =sk.accept()
p=Process(target=fun1,args=(conn,)) #将发送端设置为子进程 循环来一个我就送一个
p.start()
>>>>>>>>>>>>>>

    七:买票的小例子    

      # 多个进程 抢占同一个数据资源 会造成 数据不安全

      # 我们必须要牺牲效率来保证数据的安全性

数据结构:

{"count": 0}
import json
import time
from multiprocessing import Lock
from multiprocessing import Process
def search(name): #查询票
with open('ticket.txt') as f :
ticket_count =json.load(f) #解析句柄
if ticket_count['count'] >= :
print('%s:有余票%s 张'%(name,ticket_count['count']))
else:
print('%s:没票了'%name)
def buy(name): #买票
with open('ticket.txt') as f :
ticket_count = json.load(f) # 解析句柄
time.sleep(0.2)
if ticket_count['count'] >= :
print('%s:有余票%s 张' % (name, ticket_count['count']))
ticket_count['count']-=
print('%s:买到票了'%name)
else: print('%s:没票了' % name)
time.sleep(0.2)
with open('ticket.txt', 'w') as f:
json.dump(ticket_count, f)
def opt(lock,name): #设置锁函数
search(name)
lock.acquire() #拿走钥匙
buy(name)
lock.release() #归还钥匙 #总计就一把钥匙,第一个拿到的人可以操作其他人操作不了只能等着
if __name__ == '__main__':
lock =Lock() #锁, 互斥锁
for i in range():
p =Process(target=opt,args=(lock,'wzh'+str(i)))
p.start()
>>>>>>>>>>> wzh3:有余票3 张
wzh0:有余票3 张
wzh1:有余票3 张
wzh2:有余票3 张
wzh3:有余票3 张
wzh3:买到票了
wzh4:有余票3 张
wzh5:有余票2 张
wzh6:有余票2 张
wzh0:有余票2 张
wzh0:买到票了
wzh7:有余票1 张
wzh1:有余票1 张
wzh1:买到票了
wzh8:有余票1 张
wzh9:有余票1 张
wzh2:没票了
wzh4:没票了
wzh5:没票了
wzh6:没票了
wzh7:没票了
wzh8:没票了
wzh9:没票了

    八:队列的概念

        

# 进程之间的通信
# IPC Iter Process Communication
# IPC :管道Pipe(没有锁,数据不安全的),管道 + 锁 == 队列
# 第三方工具(消息中间件) :memcache、redis、kafka、rabbitmq
# 队列的用法 + 模型

         1:queque包

     >

    

#队列
# 队列的作用, 队列的作用就是先进先出,后进后出
import queue #队列, 先进先出
q = queue.Queue() #实例化对象
# print(q) #<queue.Queue object at 0x009D4670>
q.put() #按照顺序往队列里放
q.put()
q.put()
print(q.get()) # #按照顺序放队列里拿
print(q.get()) #
print(q.get()) #3
>>>>>>>>>>

1
2
3

 

        2:from multiprocessing import Queue #进程中的Queue 包

from multiprocessing import Process
from multiprocessing import Queue #进程中的Queue 包
def son(q):
msg =q.get()
msg1 =q.get()
msg2 =q.get()
print(msg)
print(msg1)
print(msg2)
if __name__ == '__main__':
q =Queue() # 该方法是socket +pickle +Lock 实现的
pro =Process(target=son,args=(q,)) #创建进程里面扔进去队列
pro.start()
q.put('hello')
q.put('hello1')
q.put('hello2')
pro.join() >>>>>>>>
hello
hello1
hello2

  

    十:生产者消费者模式

# 生产者消费者模型
# 为什么会有这个模型

# 使用队列来完成生产、消费的过程
# 生产者 是进程
# 消费者 是进程
# 生产者和消费者之间 传递数据 是需要一个 盘子(IPC)
# 队列

  

import time
from multiprocessing import Process #导入进程包
from multiprocessing import Queue #导入对列包 Queue 里面包含了Lock
def consumer(name,q): #q是管道,
while True: #因为不知道要生产多少个,所以这里用while True
food =q.get() # 从队列中拿出1个字符串
if not food: #如果拿不到那么 break
break
time.sleep(1.5)
print('%s吃了一个%s'%(name,food)) def producter(q,food_name):
for i in range(): #总共生产10个
time.sleep(0.5)
food ='%s%s'%(food_name,i) #生产食物几
print('制造了%s'%food)
q.put(food) #把食物放在队列中,如果队列满了这里就开始堵塞了,直到队列中有空的位置才继续
if __name__ == '__main__':
q =Queue() #qsize 是这个队列的容量, 一般设置为cpu数量加1 就够了
p1 =Process(target=consumer,args=('wzh',q)) #俩个消费者,消费者1号
p2 =Process(target=consumer,args=('zsf',q)) #消费者2号
p5 =Process(target=consumer,args=('Wf',q)) #消费者2号
p6=Process(target=consumer,args=('Lf',q)) #消费者2号
p3 =Process(target=producter,args=(q,'baozi')) #生产者1号
p4 =Process(target=producter,args=(q,'jiucai')) #生产者2号
p1.start() #启动消费者1号
p2.start() #启动消费者2号
p5.start() #启动消费者3号
p6.start() #启动消费者4号
p3.start() #启动生产1号
p4.start() #启动生产者2号
p3.join() #确定3号生产者生产完毕
p4.join() #确定4号生产者生产完毕
q.put(None) #让队列消费者停止使用
q.put(None)
q.put(None)
q.put(None)
>>>>

制造了baozi0
制造了jiucai0
制造了baozi1
制造了jiucai1
制造了baozi2
制造了jiucai2
wzh吃了一个baozi0
制造了baozi3
zsf吃了一个jiucai0
制造了jiucai3
Lf吃了一个baozi1
制造了baozi4
Wf吃了一个jiucai1
制造了jiucai4
制造了baozi5
制造了jiucai5
wzh吃了一个baozi2
制造了baozi6
zsf吃了一个jiucai2
制造了jiucai6
Lf吃了一个baozi3
制造了baozi7
Wf吃了一个jiucai3
制造了jiucai7
制造了baozi8
制造了jiucai8
wzh吃了一个baozi4
制造了baozi9
zsf吃了一个jiucai4
Lf吃了一个baozi5
制造了jiucai9
Wf吃了一个jiucai5
wzh吃了一个baozi6
zsf吃了一个jiucai6
Lf吃了一个baozi7
Wf吃了一个jiucai7
wzh吃了一个baozi8
zsf吃了一个jiucai8
Lf吃了一个baozi9
Wf吃了一个jiucai9

 

    

     十一:数据之间的共享

# Manager提供很多数据共享的机制,但是对于一些基础数据类型来说,是数据不安全的
# 如何去解决问题呢?需要我们自己来做加锁的工作
from multiprocessing import Process
from multiprocessing import Manager #进程之间数据共享
from multiprocessing import Lock
def work(d,lock):
# lock.acquire()
# d['count']-=
# lock.release()
# with lock: #通过锁进行操作数据之间的共享
d['count'] -=
if __name__ == '__main__':
lock =Lock() #实例化锁的对象
m =Manager() #实例化数据共享模块
dic =m.dict({'count':})
p_lis =[]
for i in range():
p =Process(target=work,args=(dic,lock))
p_lis.append(p)
p.start()
for p in p_lis:
p.join()
print(dic)
>>>>>>>>>>

{'count': 95}
{'count': 95}
{'count': 95}
{'count': 91}
{'count': 91}
{'count': 91}
{'count': 90}
{'count': 90}
{'count': 90}
{'count': 90}

 

  

    十二:进程池的概念

# 起多进程的意义
# 1.为了更好的利用CPU,所以如果我们的程序中都是网络IO,文件IO就不适合起多进程
# 2.为了数据的隔离,如果我们的程序中总是要用到数据共享,那么就不适合使用多进程
# 3.超过了cpu个数的任务数,都应该使用进程池来解决问题,而不能无限的开启子进程

# 如果我们有多少个任务 就开启多少个进程 实际上对我们来说 是不划算的
# 由于我们计算机的cpu个数是非常有限的
# 所以我们起的进程数量是完全和CPU个数成比例的
import os
import time
from multiprocessing import Pool
def fun1(i):
time.sleep()
print(i,os.getpid())
if __name__ == '__main__':
p =Pool() #创建进程池 #经测试是4个4个处理的
for i in range():
p.apply_async(fun1,args=(i,)) #传入方法名, 函数参数元祖扩住
p.close() #关闭池子, 不是回城池子中的进程,而是阻止继续向池子中继续提交任务
p.join() #阻塞,直到池子中的任务全部都执行完毕
>>>>>>>>

    十三:进程池与进程之间的性能测试

import os
import time
from multiprocessing import Process #导入进程
from multiprocessing import Pool #导入进程池
def fun1(i):
print(i,os.getpid()) #打印内容以及当前进程的id
if __name__ == '__main__':
start_time =time.time()
p_lis =[]
for i in range():
p =Process(target=fun1,args=(i,))
p.start()
p_lis.append(p)
for p in p_lis:
p.join()
end_time =time.time()
pro_time =end_time-start_time
start =time.time()
pool = Pool()
for i in range():
pool.apply_async(fun1,args=(i,))
pool.close() #关闭池子
pool.join() #阻塞直到所有的任务都完成
end =time.time()
pool_time =end-start
print(pool_time ,pro_time)
>>>>>>>>>> 2.412966251373291 7.410228252410889
可以出 进程池的时间远远短于 进程 所以推荐使用进程池

    

    十四:进程池的其他机制:

      1:map()的用法

import os
import time
from multiprocessing import Pool
def fun1(i):
time.sleep(0.5)
print(i,os.getpid())
if __name__ == '__main__':
p =Pool()
# for i in range():
# p.apply_async(fun1,args=(,))
p.map(fun1,range()) #用map 可以表示上面的两个注释的
>>>>>>>>>>>>>

0 13872
1 8412
2 14112
3 10968
4 13872
6 14112
5 8412
7 10968
8 13872
9 8412

       2:进程池可以有返回值(在主进程打印)

import os
import time
from multiprocessing import Pool
def fun1(i):
time.sleep(0.5)
print(i,os.getpid()) #
return i*i #返回i*i
if __name__ == '__main__':
p =Pool()
ret_lis =[] #用来接收每一个返回值
for i in range():
ret =p.apply_async(fun1,args=(i,)) #返回值
ret_lis.append(ret)
p.close() #关闭池子
p.join() #阻塞,直到子进程全部结束
for rets in ret_lis:
print(rets.get())
>>>>>>>>>>>>>

      3:进程池的回调函数:

import time
import random
from multiprocessing import Process,Pool
def get(i): # 进程池的子进程执行的
time.sleep(random.random())
print('从网页获取一个网页的内容', i)
return i,'网页的内容'*i
def call_back(content): # 主进程执行的,content接受上面的get方法
print(content)
if __name__ == '__main__':
p = Pool()
ret_l = []
for i in range():
p.apply_async(get,args=(i,),callback=call_back)
p.close()
p.join()
>>>>>

从网页获取一个网页的内容 4
(4, '网页的内容网页的内容网页的内容网页的内容')
从网页获取一个网页的内容 2
(2, '网页的内容网页的内容')
从网页获取一个网页的内容 1
(1, '网页的内容')
从网页获取一个网页的内容 0
(0, '')
从网页获取一个网页的内容 3
(3, '网页的内容网页的内容网页的内容')
从网页获取一个网页的内容 9
(9, '网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容')
从网页获取一个网页的内容 5
(5, '网页的内容网页的内容网页的内容网页的内容网页的内容')
从网页获取一个网页的内容 7
(7, '网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容')
从网页获取一个网页的内容 6
(6, '网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容')
从网页获取一个网页的内容 8
(8, '网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容网页的内容')

 

---恢复内容结束---

day 28 :进程相关,进程池,锁,队列,生产者消费者模式的更多相关文章

  1. python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型

    1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...

  2. Linux进程通信之共享内存实现生产者/消费者模式

    共享内存 共享内存是内核为进程创建的一个特殊内存段,它将出现在进程自己的地址空间中,其它进程可以将同一段共享内存连接(attach)到自己的地址空间.这是最快的进程间通信方式,但是不提供任何同步功能( ...

  3. 10 阻塞队列 & 生产者-消费者模式

    原文:http://www.cnblogs.com/dolphin0520/p/3932906.html 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(Li ...

  4. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))

    昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...

  5. Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型

    Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: ​ ​ ​ 每个对象都对应于一个可称为" 互斥锁&qu ...

  6. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  7. python开发进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  8. 5 并发编程-(进程)-队列&生产者消费者模型

    1.队列的介绍 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的 创建队列的类(底层就是以管道和锁定的方式实现 ...

  9. python3全栈开发-多进程的守护进程、进程同步、生产者消费者模式(重点)

    一.守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes a ...

随机推荐

  1. 13.Roman to Integer (HashTable)

    Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 t ...

  2. mac下yii安装

    下载https://github.com/yiisoft/yii2-app-advanced/releases,里边没index.php文件 1.http://www.yiichina.com/que ...

  3. OPENSSL 生成https 客户端证书

    下面说下拿服务器证书.(前提是服务器是https,客户端认证用的时候),服务端不给的时候,我们自己去拿(不给怼他!,哈哈,开个玩笑,都会给的) openssl s_client -connect 域名 ...

  4. c语言寄存器变量

    寄存器存在于CPU内部,运算速度非常快, 因为内存中的数据必须载入寄存器才能计算.如果直接定义一个变量为寄存器变量,则少了载入等过程自然会快.对于频繁使用的变量可以把它放在寄存器中来提速度. 对于VC ...

  5. php多进程pcntl学习(二)

    多进程中数据独立,变量无法共享,所以可以使用shmop共享内存实现(cli模式不支持APC扩展),或者存储到redis这种nosql中. 下面实例,开10个进程结合redis集合,做一些简单的任务处理 ...

  6. [Selenium] 最大化或自定义浏览器的大小

      driver.manage().window().maximize(); //将浏览器设置为最大化的状态   driver.manage().window().setSize(new Dimens ...

  7. Spring boot——logback.xml 配置详解(二)

    阅读目录 1 根节点包含的属性 2 根节点的子节点 文章转载自:http://aub.iteye.com/blog/1101260,在此对作者的辛苦表示感谢! 回到顶部 1 根节点<config ...

  8. java内存溢出异常

    名称 特征 作用 配置参数 异常 程序 计数器 占用内存小,线程私有, 生命周期与线程相同 大致为字节码行号指示器 无 无 虚拟机栈 线程私有,生命周期与线程 相同,使用连续的内存空间 Java 方法 ...

  9. eclipse启动tomcat出现内存溢出错误 java.lang.OutOfMemoryError: PermGen space

    发布工程后,启动tomcat出现如下内存溢出错误: java.lang.OutOfMemoryError: PermGen space ... java.lang.OutOfMemoryError: ...

  10. 如何把asp.net上的服务在iis调试

    1,在iis上部署一个应用,路径指向工程目录 2,在vs2012(其他版本没试过,10都很久没用不记得了)中打开网站,选择本地iis 3,在你想调试的地方设置断点,F5,搞定!