python 同步 互斥 信号量 锁 简介

Love The Way You Lie 2021-09-02 08:56 653阅读 0赞

目录

进程间的信号

信号量(信号灯)

进程的同步互斥

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 :信号名称

  1. import os
  2. import signal
  3. os.kill(12345,signal.SIGKILL) #杀死进程

signal.alarm(time)

个人理解:把发送信号的信息告知系统内核,应用层程序继续运行,时间到之后利用内核告知应用层程序进行处理

功能:非阻塞函数,向自身进程发送一个时钟信号

参数:time->整型时间秒

  1. import signal
  2. import time
  3. signal.alarm(3)#3秒后向自身发送一个时钟信号
  4. while True:
  5. time.sleep(1)
  6. print("等待时钟信号")
  7. '''打印结果
  8. 等待时钟信号
  9. 等待时钟信号
  10. 闹钟
  11. '''
  12. signal.alarm(3)#3秒后向自身发送一个时钟信号
  13. time.sleep(2)
  14. signal.alarm(5)#进程只有一个时钟信号,第二个会覆盖上面的时钟信号
  15. while True:
  16. time.sleep(1)
  17. print("等待时钟信号")
  18. '''打印结果
  19. 等待时钟信号
  20. 等待时钟信号
  21. 等待时钟信号
  22. 等待时钟信号
  23. 闹钟
  24. '''

signal.pause()

功能:阻塞进程,然后等待信号

signal.signal(signum, handler)

功能:处理信号

参数

signum:要处理的信号

handler:信号的处理方法

SIG_DFL表示使用默认方法处理

SIG_IGN表示忽略这个信号

function表示传入一个函数,用指定的函数处理

def function(sig, frame)

sig:捕获到的信号

frame:信号对象

  1. import signal
  2. from time import sleep
  3. signal.alarm(5) # 5秒后向自身发送一个时钟信号
  4. # 使用信号的默认方法处理
  5. # signal.signal(signal.SIGALRM,signal.SIG_DFL)
  6. # 忽略时钟信号
  7. # signal.signal(signal.SIGALRM,signal.SIG_IGN)
  8. # 忽略Ctrl+c信号
  9. # signal.signal(signal.SIGINT,signal.SIG_IGN)
  10. while True:
  11. sleep(2)
  12. print("等待时钟...")
  13. # 使用自定义函数处理信号
  14. import signal
  15. from time import sleep
  16. def fun1(sig, frame):
  17. if sig == signal.SIGALRM :
  18. print("接收到时钟信号")
  19. elif sig == signal.SIGINT :
  20. print("ctrl+c就不结束")
  21. signal.alarm(5) # 5秒后向自身发送一个时钟信号
  22. # 使用自定义函数处理信号
  23. # 处理时钟信号
  24. signal.signal(signal.SIGALRM,fun1)
  25. # 处理ctrl+c信号
  26. signal.signal(signal.SIGINT,fun1)
  27. while True:
  28. print("等待")
  29. sleep(2)
  30. '''打印结果
  31. 等待
  32. 等待
  33. 等待
  34. 接收到时钟信号
  35. 等待
  36. ...
  37. '''

信号量(信号灯)

原理:给定一个数量对多个进程可见,且多个进程都可以操作,进程可以对数量多少的判断执行各自的行为

  1. from multiprocessing import Semaphore
  2. sem = Semaphore(num)

功能:创建信号量

参数:信号量的初始值

返回值:信号量的对象

sem.get_value():获取信号量的值

sem.acquire():将信号量 -1,当信号为0时会阻塞

sem.release():将信号量 +1

  1. from multiprocessing import Semaphore, Process
  2. # 创建信号量对象
  3. sem = Semaphore(num)
  4. def fun():
  5. print("进程%d等待信号量"%os.getpid())
  6. # 消耗一个信号量
  7. sem.acquire()
  8. print("进程%d消耗信号量"%os.getpid())
  9. # 添加一个信号量
  10. sem.release()
  11. print("进程%d添加信号量"%os.getpid())
  12. jobs = []
  13. for i in range(4):
  14. p = Process(target = 4)
  15. jobs.append(p)
  16. p.start()
  17. for i in jobs:
  18. i.join()
  19. 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():事件状态判断,判断事件是否处于被设置的状态

  1. from multiprocessing import Event
  2. # 创建事件对象
  3. e = Event()
  4. # 查看
  5. print(e.is_set()) # False
  6. e.set()
  7. print(e.is_set()) # True
  8. e.wait(3)
  9. print(e.is_set()) # True
  10. e.clear()
  11. print(e.is_set()) # False
  12. from multiprocessing import Event,Process
  13. from time import sleep
  14. def wait_event1():
  15. print("1想操作临界区资源")
  16. e.wait()
  17. print("1开始操作临界区资源",e.is_set())
  18. with open("file") as f:
  19. print(f.read())
  20. def wait_event2():
  21. print("2也想操作临界区资源")
  22. # 超时3秒检测
  23. e.wait(3)
  24. # 判断是否被设置
  25. if e.is_set():
  26. print("2开始操作临界区资源",e.is_set())
  27. with open("file") as f:
  28. print(f.read())
  29. else:
  30. print("2不能操作")
  31. # 创建事件对象
  32. e = Event()
  33. p1 = Process(target = wait_event1)
  34. p2 = Process(target = wait_event2)
  35. p1.start()
  36. p2.start()
  37. print("主进程操作")
  38. with open("file",'w') as f:
  39. f.write("HELLO WORD")
  40. # 延迟4秒释放临界区
  41. sleep(4)
  42. # 释放临界区资源
  43. e.set()
  44. print("释放临界区")
  45. p1.join()
  46. p2.join()

Lock 锁

from multiprocessing import Lock

lock = Lock():创建一个锁对象

lock.acquire():上锁,如果已经是上锁状态,调用此函数会阻塞

lock.release():解锁

  1. from multiprocessing import Lock,Process
  2. import sys
  3. def writer1():
  4. # 上锁
  5. lock.acquire()
  6. for i in range(20):
  7. sys.stdout.write("writer1111\n")
  8. # 解锁
  9. lock.release()
  10. def writer2():
  11. # 上锁
  12. lock.acquire()
  13. for i in range(20):
  14. sys.stdout.write("writer2222\n")
  15. # 解锁
  16. lock.release()
  17. lock = Lock()
  18. w1 = Process(target = writer1)
  19. w2 = Process(target = writer2)
  20. w1.start()
  21. w2.start()
  22. w1.join()
  23. w2.join()

第二种方法

使用with语句上锁,with语句执行完毕后会自动解

  1. with lock:
  2. .....
  3. .....

发表评论

表情:
评论列表 (有 0 条评论,653人围观)

还没有评论,来说两句吧...

相关阅读

    相关 互斥、条件变信号

    Linux 下c语言多线程编程二  4.2 互斥锁     互斥锁用来保证一段时间内只有一个线程在执行一段代码。必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得

    相关 信号互斥

    号量(semaphore) 信号量是E.W.Dijkstra提出的方法,它使用一个整型变量来累计唤醒次数,供以后使用。一个信号量的取值可以为0,或者为正值。 信