Python多进程,同步互斥,信号量,锁补充上一篇文章

步骤:1、新建信号量对象,设置信号量数量
2、线程执行方法中,如果能够获取信号量,则执行,信号量为0不可以获取

进程补充进程间的信号信号量进程的同步互斥Event事件Lock 锁

金沙官网线上 1金沙官网线上 2

进程补充

 1 import  threading,time
 2 
 3 class  MyThread(threading.Thread):
 4     def  run(self):
 5         if  sema.acquire():
 6             print(self.name)
 7             time.sleep(0.3)
 8             sema.release()
 9 
10 if __name__ == '__main__':
11     sema = threading.BoundedSemaphore(5)  # sema=threading.Semaphore(5)
12     thrs = []
13     for i in range(100):
14         thrs.append(MyThread())
15     for t in thrs:
16         t.start()

进程间的信号

信号是唯一的异步通信方法

一个进程向另一个进程发送一个信号来传递某种信息,接受者根据传递的信息来做相应的事

$ 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:要发送信号的PID号
      • sig :信号名称

金沙官网线上 3金沙官网线上 4

   import osimport signalos.kill(12345,signal.SIGKILL) #杀死进程

View Code

  • signal.alarm

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

  • 功能:非阻塞函数,向自身进程发送一个时钟信号
  • 参数:time->整型时间秒
  • 金沙官网线上 5金沙官网线上 6

         import signal  import time  signal.alarm#3秒后向自身发送一个时钟信号  while True:      time.sleep(1)      print("等待时钟信号")        '''打印结果  等待时钟信号  等待时钟信号  闹钟  '''        
    

    View Code金沙官网线上 7金沙官网线上 8

         signal.alarm#3秒后向自身发送一个时钟信号  time.sleep(2)  signal.alarm#进程只有一个时钟信号,第二个会覆盖上面的时钟信号  while True:      time.sleep(1)      print("等待时钟信号")        '''打印结果  等待时钟信号  等待时钟信号  等待时钟信号  等待时钟信号  闹钟  '''
    

    View Code

  • signal.pause()
  • 功能:阻塞进程,然后等待信号
  • signal.signal(signum, handler)
  • 功能:处理信号
  • 参数
  • signum:要处理的信号

    • handler:信号的处理方法

      • SIG_DFL表示使用默认方法处理

      • SIG_IGN表示忽略这个信号

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

        • def function(sig, frame)

          sig:捕获到的信号

          frame:信号对象

金沙官网线上 9View金沙官网线上 10金沙官网线上 11

  import signal  from time import sleep    signal.alarm  # 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("等待时钟...")

View Code金沙官网线上 12金沙官网线上 13

  # 使用自定义函数处理信号  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秒后向自身发送一个时钟信号  # 使用自定义函数处理信号  # 处理时钟信号  signal.signal(signal.SIGALRM,fun1)      # 处理ctrl+c信号  signal.signal(signal.SIGINT,fun1)    while True:      print("等待")      sleep(2)        '''打印结果  等待  等待  等待  接收到时钟信号  等待  ...  '''   

View Code

View Code

信号量

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

from multiprocessing import Semaphore

  • sem = Semaphore

    • 功能:创建信号量
    • 参数:信号量的初始值
    • 返回值:信号量的对象
  • sem.get_value():获取信号量的值

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

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

金沙官网线上 14金沙官网线上 15

from multiprocessing import Semaphore, Process# 创建信号量对象sem = Semaphoredef fun():    print("进程%d等待信号量"%os.getpid    # 消耗一个信号量    sem.acquire()    print("进程%d消耗信号量"%os.getpid    # 添加一个信号量    sem.release()    print("进程%d添加信号量"%os.getpidjobs = []for i in range(4):    p = Process(target = 4)    jobs.append    p.start()for i in jobs:    i.join()print(sem.get_value

View Code

 

进程的同步互斥

临界资源:多个进程或者线程都能操作的共享资源

临界区:操作临界区资源的代码段

同步:同步是一种合作关系,为完成某个任务,多进程或者多线程之间形成的一种协调关系

互斥:互斥是一种制约关系,

 

Event事件

from multiprocessing import Event

  • e = Event():创建一个事件对象
  • e.wait([timeout]):设置事件阻塞
  • e.set():事件设置,当事件被设置后e.wait()不再阻塞,等于释放资源区
  • e.clear():清除设置,当事件被设置e.clear()后,e.wait()又会阻塞,阻塞资源区
  • e.is_set():事件状态判断,判断事件是否处于被设置的状态

金沙官网线上 16金沙官网线上 17

from multiprocessing import Event# 创建事件对象e = Event()# 查看print(e.is_set        # Falsee.set()print(e.is_set        # Truee.wait(3)print(e.is_set        # Truee.clear()print(e.is_set        # False

View Code金沙官网线上 18金沙官网线上 19

from multiprocessing import Event,Processfrom time import sleepdef wait_event1():    print("1想操作临界区资源")    e.wait()    print("1开始操作临界区资源",e.is_set    with open("file") as f:        printdef wait_event2():    print("2也想操作临界区资源")    # 超时3秒检测    e.wait(3)    # 判断是否被设置    if e.is_set():        print("2开始操作临界区资源",e.is_set        with open("file") as f:            print    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()

View Code

例子:

Lock 锁

from multiprocessing import Lock

  • lock = Lock()金沙官网线上,:创建一个锁对象
  • lock.acquire():上锁,如果已经是上锁状态,调用此函数会阻塞
  • lock.release():解锁

金沙官网线上 20金沙官网线上 21

from multiprocessing import Lock,Processimport sysdef writer1():    # 上锁    lock.acquire()    for i in range(20):        sys.stdout.write("writer1111n")    # 解锁    lock.release() def writer2():    # 上锁    lock.acquire()    for i in range(20):        sys.stdout.write("writer2222n")    # 解锁    lock.release()lock = Lock()w1 = Process(target = writer1)w2 = Process(target = writer2)w1.start()w2.start()w1.join()w2.join()

View Code

第二种方法

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

with lock:    .....    .....    

### 强行改的信号量

本文由金沙官网线上发布于编程,转载请注明出处:Python多进程,同步互斥,信号量,锁补充上一篇文章

您可能还会对下面的文章感兴趣: