Python多进程,同步互斥,信号量,锁补充上一篇文章
2021-06-30 14:04
进程补充进程间的信号信号量(信号灯)进程的同步互斥Event事件Lock 锁
进程补充
进程间的信号
信号是唯一的异步通信方法
一个进程向另一个进程发送一个信号来传递某种信息,接受者根据传递的信息来做相应的事
$ kill -l
查看系统信号说明
$ kill -9 pid号
对进程发送信号
信号名称 | 说明 | ||
---|---|---|---|
1) SIGHUP | 连接断开 | ||
2) SIGINT | ctrl+c | ||
3) SIGQUIT | ctrl+\ | ||
20) SIGTSTP | ctrl+z | ||
9) SIGKILL | 终止进程 | ||
19) SIGSTOP | 暂停进程 | ||
26) SIGVTALRM | 时钟信号 | ||
17) SIGCHLD | 子进程退出时给父进程发的信号 | ||
在Python中import signal
可以获取信号
-
os.kill(pid, sig)
-
功能:发送信号
-
参数
- pid:要发送信号的PID号
- sig :信号名称
-
import os import signal os.kill(12345,signal.SIGKILL) #杀死进程
-
signal.alarm(time)
个人理解:把发送信号的信息告知系统内核,应用层程序继续运行,时间到之后利用内核告知应用层程序进行处理
- 功能:非阻塞函数,向自身进程发送一个时钟信号
- 参数:time->整型时间秒
-
import signal import time signal.alarm(3)#3秒后向自身发送一个时钟信号 while True: time.sleep(1) print("等待时钟信号") ‘‘‘打印结果 等待时钟信号 等待时钟信号 闹钟 ‘‘‘
signal.alarm(3)#3秒后向自身发送一个时钟信号 time.sleep(2) signal.alarm(5)#进程只有一个时钟信号,第二个会覆盖上面的时钟信号 while True: time.sleep(1) print("等待时钟信号") ‘‘‘打印结果 等待时钟信号 等待时钟信号 等待时钟信号 等待时钟信号 闹钟 ‘‘‘
signal.pause()
- 功能:阻塞进程,然后等待信号
signal.signal(signum, handler)
- 功能:处理信号
- 参数
-
signum:要处理的信号
-
handler:信号的处理方法
-
SIG_DFL
表示使用默认方法处理 -
SIG_IGN
表示忽略这个信号 -
function
表示传入一个函数,用指定的函数处理-
def function(sig, frame)
sig:捕获到的信号
frame:信号对象
-
-
-
import signal from time import sleep signal.alarm(5) # 5秒后向自身发送一个时钟信号 # 使用信号的默认方法处理 # signal.signal(signal.SIGALRM,signal.SIG_DFL) # 忽略时钟信号 # signal.signal(signal.SIGALRM,signal.SIG_IGN) # 忽略Ctrl+c信号 # signal.signal(signal.SIGINT,signal.SIG_IGN) while True: sleep(2) print("等待时钟...")
# 使用自定义函数处理信号 import signal from time import sleep def fun1(sig, frame): if sig == signal.SIGALRM : print("接收到时钟信号") elif sig == signal.SIGINT : print("ctrl+c就不结束") signal.alarm(5) # 5秒后向自身发送一个时钟信号 # 使用自定义函数处理信号 # 处理时钟信号 signal.signal(signal.SIGALRM,fun1) # 处理ctrl+c信号 signal.signal(signal.SIGINT,fun1) while True: print("等待") sleep(2) ‘‘‘打印结果 等待 等待 等待 接收到时钟信号 等待 ... ‘‘‘
信号量(信号灯)
原理:给定一个数量对多个进程可见,且多个进程都可以操作,进程可以对数量多少的判断执行各自的行为
from multiprocessing import Semaphore
-
sem = Semaphore(num)
- 功能:创建信号量
- 参数:信号量的初始值
- 返回值:信号量的对象
-
sem.get_value()
:获取信号量的值 -
sem.acquire()
:将信号量 -1,当信号为0时会阻塞 -
sem.release()
:将信号量 +1
from multiprocessing import Semaphore, Process # 创建信号量对象 sem = Semaphore(num) def fun(): print("进程%d等待信号量"%os.getpid()) # 消耗一个信号量 sem.acquire() print("进程%d消耗信号量"%os.getpid()) # 添加一个信号量 sem.release() print("进程%d添加信号量"%os.getpid()) jobs = [] for i in range(4): p = Process(target = 4) jobs.append(p) p.start() for i in jobs: i.join() print(sem.get_value())
进程的同步互斥
临界资源:多个进程或者线程都能操作的共享资源
临界区:操作临界区资源的代码段
同步:同步是一种合作关系,为完成某个任务,多进程或者多线程之间形成的一种协调关系
互斥:互斥是一种制约关系,
Event事件
from multiprocessing import Event
-
e = Event()
:创建一个事件对象 -
e.wait([timeout])
:设置事件阻塞 -
e.set()
:事件设置,当事件被设置后e.wait()
不再阻塞,等于释放资源区 -
e.clear()
:清除设置,当事件被设置e.clear()
后,e.wait()
又会阻塞,阻塞资源区 -
e.is_set()
:事件状态判断,判断事件是否处于被设置的状态
from multiprocessing import Event # 创建事件对象 e = Event() # 查看 print(e.is_set()) # False e.set() print(e.is_set()) # True e.wait(3) print(e.is_set()) # True e.clear() print(e.is_set()) # False
from multiprocessing import Event,Process from time import sleep def wait_event1(): print("1想操作临界区资源") e.wait() print("1开始操作临界区资源",e.is_set()) with open("file") as f: print(f.read()) def wait_event2(): print("2也想操作临界区资源") # 超时3秒检测 e.wait(3) # 判断是否被设置 if e.is_set(): print("2开始操作临界区资源",e.is_set()) with open("file") as f: print(f.read()) else: print("2不能操作") # 创建事件对象 e = Event() p1 = Process(target = wait_event1) p2 = Process(target = wait_event2) p1.start() p2.start() print("主进程操作") with open("file",‘w‘) as f: f.write("HELLO WORD") # 延迟4秒释放临界区 sleep(4) # 释放临界区资源 e.set() print("释放临界区") p1.join() p2.join()
Lock 锁
from multiprocessing import Lock
-
lock = Lock()
:创建一个锁对象 -
lock.acquire()
:上锁,如果已经是上锁状态,调用此函数会阻塞 -
lock.release()
:解锁
from multiprocessing import Lock,Process import sys def writer1(): # 上锁 lock.acquire() for i in range(20): sys.stdout.write("writer1111\n") # 解锁 lock.release() def writer2(): # 上锁 lock.acquire() for i in range(20): sys.stdout.write("writer2222\n") # 解锁 lock.release() lock = Lock() w1 = Process(target = writer1) w2 = Process(target = writer2) w1.start() w2.start() w1.join() w2.join()
第二种方法
使用with
语句上锁,with语句执行完毕后会自动解
with lock:
.....
.....
下一篇:基于JAVA实现的仿WC统计程序