1、创建进程

  守护进程(*****)

    _.daemon = True  #  _进程成为守护进程

    守护进程也是一个子进程。

    主进程的<代码>执行结束之后守护进程自动结束.

 import time
from multiprocessing import Process def func():
while True:
print('is alive')
time.sleep(0.5) def wahaha():
i = 0
while i < 5:
print(f'第{i}秒')
i += 1 if __name__ == '__main__':
Process(target=wahaha).start()
p = Process(target=func)
p.daemon = True # 这个p进程就成为守护进程了
p.start()
time.sleep(3)
print('主进程')

守护进程示例

 D:\Python36\python.exe E:/Python/草稿纸.py
第0秒
第1秒
第2秒
第3秒
第4秒
is alive
is alive
is alive
is alive
is alive
is alive
主进程 Process finished with exit code 0

结果

 import time
from multiprocessing import Process def func():
while True:
print('is alive')
time.sleep(0.5) def wahaha():
i = 0
while i < 5:
print(f'第{i}秒')
time.sleep(1)
i += 1 if __name__ == '__main__':
p2 = Process(target=wahaha)
p2.start()
p = Process(target=func)
p.daemon = True # 这个p进程就成为守护进程了
p.start()
time.sleep(3)
print('主进程')
p2.join() # 守护进程会等待p2子进程结束之后才结束守护

守护进程(join)

D:\Python36\python.exe E:/Python/草稿纸.py
is alive
第0秒
is alive
is alive
第1秒
is alive
is alive
第2秒
is alive
主进程
is alive
第3秒
is alive
is alive
第4秒
is alive
is alive Process finished with exit code 0

结果

  _.is_alive()  # 判断一个子进程是否活着

  _.terminate()  # 结束一个子进程

 import time
from multiprocessing import Process def wahaha():
i = 0
while i < 5:
print(f'第{i}秒')
time.sleep(1)
i += 1 if __name__ == '__main__':
p = Process(target=wahaha)
p.start()
time.sleep(3)
print('主进程')
print(p.is_alive()) # 判断一个子进程是否活着
p.terminate() # 结束一个子进程
print(p.is_alive()) # 判断一个子进程是否活着
time.sleep(0.1)
print(p.is_alive())

结束子进程与判断子进程活着示例

D:\Python36\python.exe E:/Python/草稿纸.py
第0秒
第1秒
第2秒
主进程
True
True
False Process finished with exit code 0

结果

  在执行结束子进程后,后面的判断子进程是否活着输出True是因为结束子进程需要时间,在结束函数还没执行完成时就执行了下一行判断,所以输出True,在沉睡0.1秒后结束进程已经执行结束,子进程结束,输出False.

2、进程同步部分

  (1)锁(*****)

    为了避免同一段代码被多个进程同时执行.

    维护数据的安全.

    降低了程序的效率.

    所有的效率都是建立在数据安全的角度上的.

    但凡涉及到并发编程都要考虑数据啥的安全性.

    我们需要在并发部分对数据修改的操作格外小心,如果涉及到数据的不安全,就需要进行加锁控制.

    lock / acquire / release的另外一种用法:

      lock 内部实现了进程之间的通信,使得谁acquire了谁release了能够在多个拥有lock参数的子程序中透明.

 from multiprocessing import Lock

 lock = Lock()
lock.acquire() # 想拿钥匙
print(1)
lock.release() # 还钥匙
lock.acquire() # 想拿钥匙
print('拿到钥匙了')
lock.release() # 还钥匙

锁_示例

D:\Python36\python.exe E:/Python/草稿纸.py
1
拿到钥匙了 Process finished with exit code 0

结果

  查票的例子

 import json
import time
from multiprocessing import Process, Lock def search(i):
with open('db') as f:
ticket_dic = json.load(f)
print(f'{i}正在查票,剩余票数:{ticket_dic["count"]}') def buy(i):
with open('db') as f:
ticket_dic = json.load(f)
time.sleep(0.2) # 模拟请求数据库的网络延时
if ticket_dic['count'] > 0:
ticket_dic['count'] -= 1
print(f'{i}买到票了')
time.sleep(0.2) # 模拟网数据库写消息的网络延迟
with open('db', 'w') as f:
json.dump(ticket_dic, f) def get_ticket(i, lock):
search(i) # 查询余票,可以多个用户同时查询
with lock:
buy(i) # 买票的操作涉及到数据修改,需要加锁来保证数据的安全 if __name__ == '__main__':
lock = Lock()
for i in range(10):
p = Process(target=get_ticket, args=(i, lock))
p.start()

文件管理版

 D:\Python36\python.exe E:/Python/草稿纸.py
1正在查票,剩余票数:3
2正在查票,剩余票数:3
3正在查票,剩余票数:3
0正在查票,剩余票数:3
4正在查票,剩余票数:3
1买到票了
6正在查票,剩余票数:3
5正在查票,剩余票数:3
9正在查票,剩余票数:3
7正在查票,剩余票数:3
8正在查票,剩余票数:3
2买到票了
3买到票了 Process finished with exit code 0

结果

 import json
import time
from multiprocessing import Process, Lock def search(i):
with open('db') as f:
ticket_dic = json.load(f)
print(f'{i}正在查票,剩余票数:{ticket_dic["count"]}') def buy(i):
with open('db') as f:
tick_dic = json.load(f)
time.sleep(0.2) # 模拟请求数据库的网络延时
if tick_dic['count'] > 0:
tick_dic['count'] -= 1
print(f'{i}买到票了')
time.sleep(0.2) # 模拟往数据库写消息的网络延时
with open('db', 'w') as f:
json.dump(tick_dic, f) def get_ticket(i, lock):
search(i) # 查询余票,可以多个用户同时查询
lock.acquire()
buy(i) # 买票的操作涉及到数据修改,需要加锁来保证数据的安全
lock.release() if __name__ == '__main__':
lock = Lock()
for i in range(10):
p = Process(target=get_ticket, args=(i, lock))
p.start()

正常版

D:\Python36\python.exe E:/Python/草稿纸.py
0正在查票,剩余票数:3
1正在查票,剩余票数:3
3正在查票,剩余票数:3
2正在查票,剩余票数:3
0买到票了
4正在查票,剩余票数:3
6正在查票,剩余票数:3
5正在查票,剩余票数:3
7正在查票,剩余票数:3
8正在查票,剩余票数:3
9正在查票,剩余票数:3
1买到票了
3买到票了 Process finished with exit code 0

结果

  (2)信号量(***)

  信号量是由 lock 加 计数器 组成的.

 from multiprocessing import Semaphore

 sem = Semaphore(4)
sem.acquire()
print(1)
sem.acquire()
print(2)
sem.acquire()
print(3)
sem.acquire()
print(4)
sem.release()
print(5)

信号量

D:\Python36\python.exe E:/Python/草稿纸.py
1
2
3
4
5 Process finished with exit code 0

结果

  商场KTV小例:

 import time
import random
from multiprocessing import Process, Semaphore def ktv(sem, i):
sem.acquire()
print(f'{i}走进KTV')
time.sleep(random.randint(1, 5))
print(f'{i}走出了KTV')
sem.release() if __name__ == "__main__":
sem = Semaphore(4)
for i in range(10):
p = Process(target=ktv, args=(sem, i))
p.start()

正常版

D:\Python36\python.exe E:/Python/草稿纸.py
1走进KTV
3走进KTV
0走进KTV
2走进KTV
1走出了KTV
7走进KTV
2走出了KTV
5走进KTV
0走出了KTV
4走进KTV
7走出了KTV
9走进KTV
3走出了KTV
6走进KTV
6走出了KTV
8走进KTV
5走出了KTV
4走出了KTV
9走出了KTV
8走出了KTV Process finished with exit code 0

结果

 import time
import random
from multiprocessing import Process, Semaphore def ktv(sem, i):
with sem:
print(f'{i}走进了KTV')
time.sleep(random.randint(1, 5))
print(f'{i}走出了KTV') if __name__ == "__main__":
sem = Semaphore(4)
for i in range(10):
p = Process(target=ktv, args=(sem, i))
p.start()

文件管理版

D:\Python36\python.exe E:/Python/草稿纸.py
0走进了KTV
2走进了KTV
1走进了KTV
3走进了KTV
0走出了KTV
4走进了KTV
2走出了KTV
6走进了KTV
3走出了KTV
5走进了KTV
4走出了KTV
8走进了KTV
1走出了KTV
9走进了KTV
8走出了KTV
7走进了KTV
9走出了KTV
7走出了KTV
6走出了KTV
5走出了KTV Process finished with exit code 0

结果

  (3)事件(**)

     from multiprocessing import Event

    控制子进程执行还是一个阻塞机制 —— 事件

    wait 方法:

      在事件中还有一个标志,

      如果这个标志是True,wait方法的执行效果就是pass,

      如果这个标志是False,wait方法的效果就是阻塞,直到这个标志变成True。

    控制标志:

      判断标志的状态 is_set,

      set方法    将标志设置为True,

      clear方法    将标志设置为False。

    事件创建之初标志的状态是False。

 from multiprocessing import Event
e = Event()
print(e.is_set())
e.wait()

事件默认标志的状态为False

D:\Python36\python.exe E:/Python/草稿纸.py
False

结果(状态阻塞)

 from multiprocessing import Event
e = Event()
e.set()
print(e.is_set())
e.wait()

改变标志位为True

D:\Python36\python.exe E:/Python/草稿纸.py
True Process finished with exit code 0

结果

  wait()  设置等待时间。但是不改变标志状态。

 import time
from multiprocessing import Event, Process def func1(e):
print('start func1')
e.wait(1) # wait()可以设置等待的时间,当等待时间结束,程序继续往下运行,标志维持原状态
print(e.is_set())
print('end func1') if __name__ == '__main__':
e = Event()
Process(target=func1, args=(e,)).start()
time.sleep(5)
e.set()

wait()设置等待时间

D:\Python36\python.exe E:/Python/草稿纸.py
start func1
False
end func1 Process finished with exit code 0

结果

    红绿灯

 import time
import random
from multiprocessing import Process, Event def traffic_light(e):
print('\033[1;31m红灯亮\033[0m')
while True:
time.sleep(2)
if e.is_set():
print('\033[1;31m红灯亮\033[0m')
e.clear()
else:
print('\033[1;32m绿灯亮\033[0m')
e.set() def car(i, e):
if not e.is_set():
print(f'car{i}正在等待通过')
e.wait()
print(f'car{i}通过') if __name__ == '__main__':
e = Event()
light = Process(target=traffic_light, args=(e,))
light.daemon = True
light.start()
car_list = []
for i in range(20):
p = Process(target=car, args=(i,e))
p.start()
time.sleep(random.randint(0,3))
car_list.append(p) for car in car_list:
car.join()

示例

D:\Python36\python.exe E:/Python/草稿纸.py
红灯亮
car0正在等待通过
绿灯亮
car0通过
car1通过
红灯亮
car2正在等待通过
绿灯亮
car2通过
红灯亮
car3正在等待通过
car4正在等待通过
car5正在等待通过
绿灯亮
car3通过
car4通过
car5通过
car6通过
car7通过
红灯亮
car8正在等待通过
绿灯亮
car8通过
红灯亮
car9正在等待通过
绿灯亮
car9通过
car10通过
红灯亮
car11正在等待通过
绿灯亮
car11通过
car12通过
car13通过
红灯亮
绿灯亮
car14通过
红灯亮
car15正在等待通过
绿灯亮
car15通过
car16通过
红灯亮
car17正在等待通过
绿灯亮
car17通过
car18通过
car19通过
红灯亮
绿灯亮 Process finished with exit code 0

结果

3、进程之间数据共享(部分)

  队列(*****)

  IPC    进程之间的通信

 from multiprocessing import Queue

 q = Queue()
q.put(1)
q.put('aaa')
q.put([1, 2, 3])
q.put({'k': 'v'})
q.put({'k', 'v'})
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())

队列可以存放的数据类型

 
   队列可以设置大小,当队列满了以后就会阻塞。
 from multiprocessing import Queue

 q = Queue(5)
q.put(1)
q.put('aaa')
q.put([1, 2, 3])
q.put({'k': 'v'})
q.put({'k', 'v'})
print(q.empty())
print(q.full())
q.put((1, 2, 3))

设置队列大小

D:\Python36\python.exe E:/Python/草稿纸.py
False
True

结果(阻塞)

 
   当队列中没有值时,get()取不到值,就会阻塞,直到队列里取到值。
 from multiprocessing import Queue
q = Queue(3)
q.get()

示例

D:\Python36\python.exe E:/Python/草稿纸.py

结果(进入阻塞)

 
  当队列中没有值时,使用get_nowait()取不到值就会报错。
 from multiprocessing import Queue
q = Queue(3)
try:
q.get_nowait()
except:
print('队列中没有值')

get_nowait()

 D:\Python36\python.exe E:/Python/草稿纸.py
队列中没有值 Process finished with exit code 0

结果

 
   当队列满了以后在put()数据进去就会进入阻塞。
 from multiprocessing import Queue

 q = Queue(3)
q.put(1)
q.put('aaa')
q.put([1, 2, 3])
q.put('alex')

队列满进入阻塞

D:\Python36\python.exe E:/Python/草稿纸.py

结果(进入阻塞)

 
   当队列满了后使用put_nowait() 不会报错,但是put_nowait()的数据会丢失。
 from multiprocessing import Queue

 q = Queue(3)
q.put(1)
q.put('aaa')
q.put([1, 2, 3])
try:
q.put_nowait('alex')
except:
print('丢了一个数据')

示例

D:\Python36\python.exe E:/Python/草稿纸.py
丢了一个数据 Process finished with exit code 0

结果

 
   多进程的情况下不准:
    empty
    full
 
  会引起程序的阻塞:
    get
    put
 
  不会引起程序的阻塞,但是程序会报错:
    get_nowait
    put_nowait  # 容易丢失数据.
 
  获得10的10次方:
from multiprocessing import Process, Queue

def  func(num, q):
q.put({num:num**num}) if __name__ == '__main__':
q = Queue()
p = Process(target=func, args=(10, q))
p.start()
print(q.get())

10**10

D:\Python36\python.exe E:/Python/草稿纸.py
{10: 10000000000} Process finished with exit code 0

结果

 
  计算 0 到 9 的对应次方
 from multiprocessing import Process, Queue

 def  func(num, q):
q.put({num:num**num}) if __name__ == '__main__':
q = Queue()
for i in range(10):
p = Process(target=func, args=(i, q))
p.start()
for i in range(10):
print(q.get())

0到9的对应次方

D:\Python36\python.exe E:/Python/草稿纸.py
{0: 1}
{2: 4}
{3: 27}
{1: 1}
{4: 256}
{6: 46656}
{7: 823543}
{8: 16777216}
{5: 3125}
{9: 387420489} Process finished with exit code 0

结果

 
  

Python_守护进程、锁、信号量、事件、队列的更多相关文章

  1. python 锁 信号量 事件 队列

    什么是python 进程锁? #同步效率低,但是保证了数据安全  重点 很多时候,我们需要在多个进程中同时写一个文件,如果不加锁机制,就会导致写文件错乱 这个时候,我们可以使用multiprocess ...

  2. python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式

    (1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...

  3. 《python》join、守护进程、锁/信号量/事件、进程队列

    一.multiprocess.process模块 1.join方法 阻塞主进程,等待子进程执行完毕再放开阻塞 import time import random from multiprocessin ...

  4. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

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

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

  6. Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures

    参考博客: https://www.cnblogs.com/xiao987334176/p/9046028.html 线程简述 什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线 ...

  7. python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...

  8. Day034--Python--锁, 信号量, 事件, 队列, 生产者消费者模型, joinableQueue

    进程同步: 1. 锁 (重点)    锁通常被用来实现对共享资源的同步访问.为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁, ...

  9. Python--day38--进程同步控制的---锁\信号量\事件的方法名

随机推荐

  1. js对WebApi请求的基本操作

    在WebAPI对外提供的,大概有4种接口,get,post,delete,put,现在,我就简单的来说一下js请求webApi的方式和大概的作用: get:在webApi中,get方法通常是用来获取数 ...

  2. 关于pycharm中使用charts无法显示图表的问题(属于个人粗心问题)

    在练习用charts库对爬取的数据进行数据分析并图表化时遇到一个问题,无法显示图表,如下: 经过重装charts库等一顿折腾后,终于发现一个问题,看这里: def data_gen(type): le ...

  3. 关于折半法查找的一些总结以及ArrayList类的总结

    一.折半法查找的总结(这算法很好理解,但我花了好久琢磨他有啥用.....) 1.实际意义 折半法查找主要是为了能够很快在一个数组中找出我们所需要的那个元素,与往常我们通过一个一个比较的方法不同,折半法 ...

  4. TLB的作用及工作过程

    下面内容摘自<步步惊芯--软核处理器内部设计分析>一书          页表一般都非常大,而且存放在内存中,所以处理器引入MMU后,读取指令.数据须要訪问两次内存:首先通过查询页表得到物 ...

  5. UVA10570-Meeting with Aliens(枚举)

    Problem UVA1616-Caravan Robbers Accept: 531  Submit: 2490Time Limit: 3000 mSec Problem Description I ...

  6. 转://Oracle 数据备份与恢复微实践

    1.模拟控制文件丢失后的数据库恢复(完全恢复) 今天的主题是备份与恢复,目的就是保护数据的安全性,众所周知Oracle之所以在市场上占据了50%的份额,与它提供了强大的数据保护措施是分不开的,下面我们 ...

  7. 【转】iOS开发笔记--识别单击还是双击

    在视图上同时识别单击手势和双击手势的问题在于,当检测到一个单击操作时,无法确定是确实是一个单击操作或者只是双击操作中的第一次点击.解决这个问题的方法就是:在检测到单击时,需要等一段时间等待第二次点击, ...

  8. HTTP请求行、请求头、请求体详解

    HTTP 请求头各参数具体含义 Header 解释 示例Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/htmlAccept-Charset 浏览器可以接 ...

  9. ssm框架的整合搭建(一)

    一个转行菜鸟半年多工作的开始学习历程............ 我是自学,也是我的记录,我学习的见证,如果你有幸看见,不要吐槽,不足之处请指点,相互学习,谢谢!! 请一起共勉!!!!!!!! 使用技术: ...

  10. 【vue】vue +element 搭建项目,在使用InputNumber 计数器时遇到的问题

    自己遇到的坑: InputNumber 计数器的change事件定义时如果不传入参数value,会产生this.num不同步的问题 <template> <el-input-numb ...