进程数据隔离.守护进程,进程同步工具

一.进程之间的数据隔离:
from multiprocessing import Process
n=100 #主程序中变量n=
def func(): global n #子进程中引用父进程中变量n,
n=n-1
return 111
if __name__=="__main__": # "子进程必须写在它下面"
n_l=[] # 创建一个新列表
for i in range(100): #计数
p=Process(target=func) #创建一个子进程,子进程对象是func
p.start() #向操作系统申请开启一个子进程 自动执行run 方法
n_l.append(p) # 将每一个子进程添加到列表中
print(n_l) #列表里是类似于<Process(Process-1, stopped)>的元素
for p in n_l: #循环遍历 每一个元素
p.join() #所有子进程都结束在执行下面的程序 print(n) #100 #结果=100 显然子进程并没有引用到父进程的变量.

进程之间的数据隔离:
总结:
1.进程与进程之间数据是隔离的,
2.内存空间是不能共享的
3.所以想要进行通信,必须借助其他手段,且这两个进程都是自愿的.
4.子进程的执行结果父进程获取不到
5.父进程如何获取子进程的执行结果:通过socket通信.
二.守护进程:
import time
from multiprocessing import Process
例一.
def func():
print("begin")
time.sleep(3)
print("wahaha")
if __name__=="__main__":
p=Process(target=func)
p.daemon=True
注意:
# 属性:守护进程的属性,默认是False,如果设置成True,就表示设置这个子进程为一个守护进程
# 守护进程的位置:设置守护进程的操作应该在开启子进程之前 p.start()
time.sleep(1)
print("主进程") #结果 只打印begin 主进程,
#例二:
def func1():
print("begin") #2打印begin
time.sleep(3) #3 休三秒
print("wahaha") #12.打印 wahaha
def func2():
while True:
print("in func2") #7.打印 in func2 9.打印infunc2
time.sleep(0.5) #8.睡0.5秒
if __name__=="__main__":
Process(target=func1).start() #1 创建一个子进程,子进程对象为func1,并向操作系统申请开启
p=Process(target=func2) #4 再创建一个子进程,子进程对象为func2,
p.daemon=True #5.设置守护进程操作
p.start() # 6.申请开启子进程func2
time.sleep(1) #10睡 1秒
print("主进程") #11.打印主进程

  

总结:
守护进程会在主进程的代码执行完毕之后直接结束,无论守护进程是否执行完毕
应用:
报活 主进程还活着
为什么要用守护进程来报活,不用主进程来工作?
守护进程报活几乎不占用CPU,也不需要操作系统去调度
主进程不能严格的每60秒就发送一条信息.
三.进程同步的工具
相关知识:
进程 : 同一时刻可以做多件事情 互相之间不影响
进程之间是异步;
进程同步的工具:锁( Lock ),信号量( Semaphore ) ,事件( Event )
同步:有先后顺序
(一). 锁Lock
from multiprocessing import Lock
lock=Lock() #创建一把锁
#两个方法
lock.acquire() #获取这把锁的钥匙
lock.release() #归还这把锁的钥匙
#抢票的例子(每个人都能查看余票,买票 import json #导入json模块
import time #导入时间模块
from multiprocessing import Process #导入Process模块
from multiprocessing import Lock #导入Lock模块
def search(i):#定义一个查票函数
with open("db","r")as f: # 2 打开文件,读取文件数据
count_dic=json.load(f) # 3 将读取数据反序列化得到数据本身
time.sleep(0.2) # 4网络延迟 从数据库中读取内容需要消耗一定的时间.
print("person%s 余票:%s张"%(i,count_dic["count"])) # 5.显示用户信息和查询数据
def buy(i): #定义一个购票函数
with open("db","r",encoding="utf-8")as f: # 8.打开文件,读取数据
count_dic=json.load(f) # 9.反序列化得到原数据
if count_dic["count"]>0: # 10.判断剩余票数是否>0
count_dic["count"]=count_dic["count"]-1 # 11.大于零则将原票数减1
print("person%s购票成功"% i) # 12显示用户购票成功
time.sleep(0.2) # 13网络延迟 (给数据库传递新票务信息需要时间)
with open("db","w",encoding="utf-8")as f: # 14打开文件
json.dump(count_dic,f) # 15 将更改后的数据写进数据库 def task(i,lock): #定义一个任务函数
search(i) # 1 执行函数search ,将序号i传给函数search
lock.acquire() # 6.用lock的acquire方法获取这把锁钥匙 (buy函数被创建的锁锁住)
buy(i) # 7.执行函数buy() 并将参数i传给函数
lock.release() # 16 用户归还钥匙
if __name__=="__main__": #必须在这一步下面创建子进程
lock=Lock() #创建一个锁lock
for i in range(10): #计数10以下
p=Process(target=task,args=(i,lock)) #创建一个子进程,子进程对象是task,有两个参数(一个是序号i,一个是加锁) 需要创建十个子进程
p.start() #申请开启一个子进程
应用:

    当多个进程共享一段数据的时候,数据会出现不安全的现象,需要加锁来维护数据的安全性
注意:
from multiprocessing import Lock
lock=Lock()
lock.acquire()
print(111)
lock.release()
lock.acquire() # 阻塞状态 (只有一把钥匙已经被获取,且尚未归还)
print(222) #不加只打印111
#解决办法: 只需要在第二次获取钥匙前将钥匙归还即加上 lock.release() 加上lock.release()就可以打印111,222
(二).信号量(Semaphore)
信号量的本质: 多把钥匙对应一把锁
lock+count计数
现象:
from multiprocessing import Process
from multiprocessing import Semaphore
sem=Semaphore(3)
sem.acquire()
print(1)
sem.acquire()
print(2)
sem.acquire()
print(3)
#sem.release()
sem.acquire() #阻塞状态 如果加sem.release()
print(4) #不打印
案例:商场唱吧(KTV)
场景:四个小房子,十个人排队等待进入房间
 import time    #导入时间模块
import random #导入random模块
from multiprocessing import Process #导入Process模块
from multiprocessing import Semaphore #导入Semaphore信号量 模块 def ktv(num,sem):#定义一个函数ktv
sem.acquire() # 1 获取一把钥匙 6 下一个用户(进程)获取钥匙
print("person%s进入ktv"% num) # 2 显示用户信息及正在使用状态
time.sleep(random.randint(1,4)) # 3 使用时间段
print("person%s离开ktv"% num) # 4 显示用户离开
sem.release() # 5 归还钥匙 if __name__=="__main__": #必须在这一条件下面创建新进程
sem=Semaphore(4) #可允许四人同时使用
for i in range(10): #计数 一共需要创建十个子进程
p=Process(target=ktv,args=(i,sem)) # 创建一个子进程p 子进程对象为ktv.需要两个参数(序号,sem)
p.start() # 申请开启一个子进程 归还钥匙后,
(三).事件(Event)
方法:
等待: wait() 如果这个标志是False 那么就阻塞
如果这个标志是True 那么就非阻塞
查看标志: is_set()
修改标志:set()将标志设置为True
clear()将标志设置为False
 现象:
from multiprocessing import Event
e = Event()
print(e.is_set()) #False 在事件创建之初默认是False
e.set() #将标志设置为True
print(e.is_set()) #True
e.wait() #相当于什么也没做
e.clear() #将标志设置为False
e.wait(timeout=10) #阻塞10秒如果信号在阻塞10s之内变为True,那么不继续阻塞直接pass,
# # 如果就阻塞10s之后状态还是没变,那么继续,
# e.wait()可以加参数 # 无论前面的wait的timeout是否通过,我的状态都不会因此改变
print(e.is_set()) #False
红绿灯模型:  控制交通灯的进程;
import time
import random
from multiprocessing import Event
from multiprocessing import Process def trafic_light(e):
print("\033[1;31m红灯亮\033[0m") # 1 打印红灯亮
while True: #2无限循环
time.sleep(2) #3睡两秒
# print(1,e.is_set()) #f
if e.is_set(): # 4.条件e.is_set()=False:阻塞
print("\033[1;31m红灯亮\033[0m") #5.打印红灯亮
e.clear() #6.修改is_set()的状态为False
# time.sleep(3)
# print(2,e.is_set()) #f
else: #7.e.si_set==True如果目前状态是True非阻塞
print("\033[1;32m绿灯亮\033[0m") #8.打印绿灯亮
# print(4, e.is_set()) #f
e.set() #9.设置is_set的状态为True 非阻塞(通行)
# print(5,e.is_set()) #T def car(i,e):#车函数 (两种情况:等待,通行)
# time.sleep(3)
# print(3,e.is_set()) #True
if not e.is_set():# 10.如果e.is_set()的状态是True 则not e.is_set()为False,现在状态是阻塞,
print("car%sd等待"% i) #11. #先提示用户进入等待状态
e.wait() #12. #直接pass
print("car%s通行"% i) #13.和条件判断并行即条件不满足执行这一步
if __name__=="__main__":
e=Event() #创建一个事件
p=Process(target=trafic_light,args=(e,)) #创建一个进程对象为trafic_light ,参数为e
p.start() #申请开启进程
for i in range(10):
p=Process(target=car,args=(i,e)) #创建十个car进程,参数为i,e
p.start() #申请开启进程
time.sleep(random.randrange(0, 3, 2)) #要么睡两秒,要么不睡.

多进程解决tcp协议一个服务器与多个客户端通信矛盾

服务器端代码:

import socket
from multiprocessing import Process #导入类Process
def talk(conn): # 定义一个函数talk .执行talk进程
try:
while True:
conn.send(b'alex') #.发送信息
print(conn.recv()) #.接收信息
finally:
conn.close() if __name__=="__main__":
sk=socket.socket() # 创建一个socket对象
sk.bind(("127.0.0.1",)) # 绑定一个IP地址接口
sk.listen() # 监听
try:
while True:
conn,addr=sk.accept() # 无限循环可支持多个客户端连接
Process(target=talk,args=(conn,)).start() # 连接以后需要开启一个正常收发信息进程.进程对象就是talk
#并向操作系统提出执行talk进程的申请.
finally:
sk.close()

客户端代码:

import socket
import os
sk=socket.socket()
sk.connect(("127.0.0.1",))
while True:
print(sk.recv())
sk.send(str(os.getpid()).encode('utf-8')) sk.close()

python开发 *进程数据隔离.守护进程,进程同步工具 * 180725的更多相关文章

  1. python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)

    #######################总结######### 主要理解 锁      生产者消费者模型 解耦用的   队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...

  2. python并发编程基础之守护进程、队列、锁

    并发编程2 1.守护进程 什么是守护进程? 表示进程A守护进程B,当被守护进程B结束后,进程A也就结束. from multiprocessing import Process import time ...

  3. Python 之并发编程之进程中(守护进程(daemon)、锁(Lock)、Semaphore(信号量))

    五:守护进程 正常情况下,主进程默认等待子进程调用结束之后再结束守护进程在主进程所有代码执行完毕之后,自动终止kill -9 进程号 杀死进程.守护进程的语法:进程对象.daemon = True设置 ...

  4. (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. Linux进程托管与守护进程设置

    引言 在上一篇<Linux启动之旅>中,我们了解了Linux启动过程,在该过程的最后一步,init进程拉起/etc/init.d/rcN.d/目录下指定的守护进程(daemon).假若自定 ...

  6. python开发最受欢迎的十款工具

    python开发最受欢迎的十款工具 dreamyla3个月前 今天小编给正在学习python开发的朋友介绍十款最受欢迎的开发工具,因为在学习python开发过程中少不了IDE或者代码编辑器,想要提高开 ...

  7. Python开发基础-Day32 进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  8. python 之 并发编程(守护进程、互斥锁、IPC通信机制)

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

  9. Python开发【笔记】:进程

    序言 进程与线程概述: 很多同学都听说过,现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统. 什么叫“多任务”呢?简单地说,就是操作系统可以同时运 ...

随机推荐

  1. chrome浏览器美化插件:让您的浏览器页面冒水泡, 游小鱼儿

    下载插件和效果图 这是一个让你的浏览器冒泡泡的插件, 浏览网页的时候仿佛置身于海底世界: 插件下载地址:http://files.cnblogs.com/files/diligenceday/chro ...

  2. 解决Maven项目总是回跳到jdk1.5的情况的方法

    一.在pom.xml中加入: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins& ...

  3. go微服务框架go-micro深度学习(三) Registry服务的注册和发现

    服务的注册与发现是微服务必不可少的功能,这样系统才能有更高的性能,更高的可用性.go-micro框架的服务发现有自己能用的接口Registry.只要实现这个接口就可以定制自己的服务注册和发现. go- ...

  4. Docker Mongo数据库主从同步配置方法

    一.具体操作方法 1.启两个Mongo容器 docker run --name mongo1 -p 21117:27017 -d mongo --noprealloc --smallfiles --r ...

  5. 关于inodes占用100%解决方法

    df -i; 发现inode节点占满: 这个时候如果不知道哪儿节点占用多可以用下边的脚本进行检查,查看到底哪个目录下面的文件最多: for i in /*; do echo $i; find $i | ...

  6. hive SQL 行转列 和 列转行

    一.行转列的使用 1.问题 hive如何将 a       b       1a       b       2a       b       3c       d       4c       d  ...

  7. 在WPF中的Canvas上实现控件的拖动、缩放

    如题,项目中需要实现使用鼠标拖动.缩放一个矩形框,WPF中没有现成的,那就自己造一个轮子:) 造轮子前先看看Windows自带的画图工具中是怎样做的,如下图: 在被拖动的矩形框四周有9个小框,可以从不 ...

  8. slackware在vagrant中使用

    slackware以简洁干净的系统闻名于世,如果你想学习了解linux,那么slackware是一个很好的选择,其他linux不是不好,他们都太复杂了,复杂的你不知道从哪里开始. 所以,还是slack ...

  9. Mac安装minikube

    安装过程 先安装minikube,使用下面命令(由于墙的问题,所以指定国内的地址) curl -Lo minikube http://kubernetes.oss-cn-hangzhou.aliyun ...

  10. 范型方法 & 范型参数 & 范型返回值

    Java范型类 public class FanXingClassTest { public static void main(String args[]){ Test<Integer> ...