Python-process模块、数据安全(lock)、队列

process模块

主进程是在子进程执行完毕之后才结束的,主进程回收子进程资源

p.join()  阻塞,直到p对应的子进程对象执行结束

from multiprocessing import Process
import time
import os
def son_process():
   print('start son', os.getpid())
   time.sleep(3)
   print('end son')
if __name__ == '__main__':
   p = Process(target=son_process)
   p.start()
   p.join()   # 阻塞,直到p对应的子进程对象执行结束
   print('所有任务结束')
   
# start son 7164
# end son
# 所有任务结束    

 

守护进程(daemon)

  • p.daemon = True    将当前的子进程设置为守护进程

守护进程会随着父进程的代码结束而结束

正常情况下  父进程永远会等着子进程结束

如果设置了守护进程   父进程的代码结束之后  守护进程也跟着结束

from multiprocessing import Process
import time
def son():
   while True:
       time.sleep(1)
       print('in son')
if __name__ == '__main__':
   p = Process(target=son)
   p.daemon = True  # 将当前的子进程设置为守护进程
   p.start()
   time.sleep(5)

偏要守护进程在子进程结束之后才结束

from multiprocessing import Process
import time
def son():
   while True:
       time.sleep(1)
       print('in son')
def son2():
   print('start son2')
   time.sleep(10)
   printt('end son2')
if __name__ == '__main__':
   p = Process(target=son)
   p.daemon = True
   p.start()
   p = Process(target=son2).start()
   time.sleep(5)
   p.join()

 

子进程结束之后,父进程才会结束

扫描二维码关注公众号,回复: 9623066 查看本文章

代码结束和进程结束是两回事

  • 没设置守护进程:

    • 1.子进程的代码和主进程的代码自己执行自己的,互相之间没有联系

    • 2.如果主进程的代码先结束,主进程不结束,等子进程代码结束,回收子进程的资源,主进程才会结束

    • 3.如果子进程先结束,主进程边回收子进程的资源边执行自己的代码,当代码和资源都回收完毕,主进程才会结束

  • 设置了守护进程

    • 1.子进程的代码和主进程的代码自己执行自己的,互相之间没有关系

    • 2.一旦主进程的代码先结束,主进程会结束掉子进程(也就是守护进程),然后回收资源,然后主进程才结束

守护进程只守护主进程代码,守护进程不会守护除了主进程代码之外的其他子进程

from multuprocessing import Process
import time
def son()
while True:
       time.sleep(1)
       print('in son')
def son2():
   print('start son2')
   time.sleep(10)
   print('end son2')
if __name__ == '__main__':
   p = Process(target=son)
   p.daemon = True
   p.start()
   Process(target=son2).start()
   time.sleep(5)

 

Process对象的方法

p.start() # 开启进程(相当于告诉操作系统要开启一个子进程,而子进程的调度是由操作系统控制的) 
p.join() # 阻塞,直到p对应的子进程结束(如果执行这句话之前子进程就结束了,那么主进程就不阻塞了)
p.terminate() # 异步结束子进程(异步非阻塞操作)
p.is__alive() # 判断进程实例是否还在运行

面向对象的方式开启进程

class MyProcess(Process):
   def run(self):
       print('son',os.getpid())
if __name__ == '__main__':
   print('father',os.getpid())
   p = MyProcess()
   p.start()

传参数

class MyProcess(Process):
def __init__(self,arg1,arg2):
       self.arg1 = arg1
       self.arg2 = arg2
   def run(self):
       print(self.arg1,self.arg2)
if __name__ == '__main__':
   print('father',os.getpid())
   p = MyProcess(1,2)
   p = start()

数据安全(锁)

锁:用来保证数据安全

如果多个进程同时对一个文件进行操作会出现什么问题

  • 1.读数据:可以同时读

  • 2.写数据:但不可以同时写

Lock

from multiprocessing import Process,Lock
def change(lock):
   print('本是青灯不归客\n一部分并发的代码,多个进程之间互相不干扰的执行着')
   lock.acquire()
   with open('file','r')as f:
  content = f.read()
   num = int(content)
   num += 1
   with open('file','w')as f:
  f.write(str(num))
   lock.release()
   print('却因浊酒留红尘\n另一部分并发的代码,多个进程之间互相不干扰的执行着')
if __name__ == '__main__':
   lock = Lock()
   p = Process(target=change,args=(lock,))
   p.start()
# 当多个进程同时操作文件/共享的一些数据的时候就会出现数据不安全
# 开启多进程 同时执行多行代码
# 其中20行涉及到了操作同一个文件
# 只给这20行代码加锁,来保证数据的安全

进程之间的通信IPC -- 队列

Inter    Process     Communication

from multiprocessing import Queue,Process
def son(q):
print(q.get())
if __name__ == '__main__':
   q = Queue()
   p = Process(target=son,args=(q,))
   p = start()
   q.put(0)

在进程之间是维护数据的安全 -- 进程安全

队列是进程安全的(进程队列保证了进程的数据安全)

队列都是先进先出

队列是基于文件+锁实现的

队列一共提供了两个方法:get/put

# q = Queue(2)  # 只能放两个
# q.put({1,2,3})
# q.put({1,2,3})
# q.put({1,2,3})   # put 是一个同步阻塞方法,会阻塞直到队列不满


# q = Queue(2)
# try:
#     for i in range(4):
#         q.put_nowait(i) # put_nowait 同步阻塞方法
# except queue.Full:
#     print(i)

# q = Queue(5)
# ret = q.qsize() # 查看当前队列有多少值
# print(ret)
# print(q.empty())
# print(q.full())

队列Queue = 管道Pipe + 锁

Pipe 基于文件实现的(socket+pickle)=  数据不安全

Queue 基于文件(socket+pickle)+ 锁(lock)实现的  =  数据安全

            基于Pipe+锁(lock)实现的

IPC:

  • 内置模块实现的机制:队列/管道

  • 第三方工具:redis  rabbitMQ  memcache

 

打印进度

import time
for i in range(101):
   print('\r当前的进度:%.2f%%'%i,end="")
   time.sleep(0.05)

猜你喜欢

转载自www.cnblogs.com/womenzt/p/12427573.html