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

前情提要:

    一:进程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. Eclipse自动补全修改

    一.前言 之前敲代码用的是文本工具sublime,转到Eclipse之后发现补全功能特别不方便,所以想根据自己的情况进行调整,具体有两点: 输入某些语句的前几个字母就能自动提示相关的完整语句 用tab ...

  2. Mybatis 实用篇(三)参数处理

    Mybatis 实用篇(三)参数处理 sql 语句中的参数 parameterType 可以省略不写. 一.参数封装 1.1 单个参数处理 public interface UserMapper { ...

  3. JQuery 对象和事件

    JQuery 对象和事件 一:JQuery 对象和 Dom 对象 在使用 JQuery 过程中,我们一般(也是绝大多数情况下,除非我们使用了第二个框架)只有两类对象,即:JQuery 对象和 Dom ...

  4. io.fabric8.kubernetes对pv和pvc的增删查改

    1.新建maven项目k8stest,pom.xml如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...

  5. CentOS 7下面配置静态IP

    CentOS 7.0系统是一个很新的版本哦,很多朋友都不知道CentOS 7.0系统是怎么去安装配置的哦,因为centos7.0与以前版本是有很大的改进哦. 说明:截止目前CentOS 7.x最新版本 ...

  6. linux每天一小步---ls命令详解

    1 命令功能: 列出当前目录下或者指定目录下的所有文件和目录,ls是list的缩写. 2 命令语法: ls [选项] [目录名]     #注:[]中的内容为非必选项 3 命令选项: -a 列出目录下 ...

  7. linux下的文本操作之 文本查找——grep

    摘要:你有没有这样的应用场景:调试一个程序,出现debug的提示信息,现在你需要定位是哪个文件包含了这个debug信息,也就是说,你需要在一个目录下的多个文件(可能包含子目录)中查找某个字符串的位置: ...

  8. cxgrid的FINDPANEL编程

    cxgrid的FINDPANEL编程 FindPanel := TcxGridFindPanel.Create(cxGrid1DBTableView1.Controller); self.cxGrid ...

  9. IntentService介绍

    1.IntentService 是什么 一个封装了HandlerThread和Handler的异步框架. 是一种特殊Service,继承自Service,是抽象类,必须创建子类才可以使用. 可用于执行 ...

  10. vs的 Avalon 自动补全

    以VS2013为例: 1.关闭 Visual Studio 2.打开 C:/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/Packa ...