同步互斥

要了解同步互斥先了解几个关于资源的概念,为什么会出现同步互斥,大多数是因为我们要对某一个资源进行争夺。在进程中出现的情况不多,多数是在进程中出现的,看下如


如上图所示,现在有两个进程分别是进程A和进程B,还有一个资源C,A想使用这个资源,B进程也想使用这个资源(前提条件是A和B都能使用这个资源)现在的情况是A进程和B进程都要使用C资源,A进程往资源里添加一个数字5,要使用这个5,B进程往资源里添加一个10,要使用这个10,结果A和B并没有商量,就会出现这么一个问题,A进程添加了5还没有来得及使用,B进程又添加了10,那么就把原来的5修改为了10,结果A在使用的时候发现已经是10了,这个时候就造成了程序之间的运行错误,这种问题在共享资源中很容易发生,如果A进程对共享资源有权限,B进程对共享资源没有权限,那么刚刚描述的问题是绝对不会发生的,因为这个共享资源是A进程专属的,B进程用不了,但是当所有的进程对共享资源都有权限的时候,这个问题就出现了,比如共享内存。

临界资源:上述描述都在竞争的资源称之为临界资源

                 官方定义:对多个进程或者线程都可见的资源,容易产生争夺,我们将这类资源称之为临界资源

临界区:指一段代码对临界资源操作的代码区称之为临界区(也就是执行代码)

解决办法:

   同步或互斥

   好多书上都描述同步也是一种高级的互斥,互斥也是某一种程度变相的同步,其实这么说主要是因为同步和互斥的目的是相同的都是为了解决临界资源争夺。

什么是同步?

      同步是一种合作关系,为完成某种任务而建立的多个进程或者线程之间的协调调用,次序等待,传递消息告知资源占用情况

什么是互斥:

     互斥是一种制约关系,当一个进程或者多个进程进入临界区后会进行加锁操作,此时其他进程(线程)无法进入临界区,只有当该进程(线程)使用后进行解锁其他人才可以使用这种技术往往是通过阻塞完成

from multiprocessing import Process,Event
from time import sleep


def wait_event(e):
    print('Process1要等主进程操作完我才能操作')
    e.wait()
    print('终于操作完了,该我了',e.is_set())

def wait_event_time(e):
    print('process2要等主进程操作完我才能操作')
    e.wait(2)
    print('我等不了了,去干别的',e.is_set())


def main_thread():
    e = Event()
    p1 = Process(name='block', target=wait_event, args=(e, ))
    p1.start()
    p2 = Process(name='non-block', target=wait_event_time, args=(e, ))
    p2.start()
    print('主进程在忙碌的操作临界区')
    sleep(3)
    e.set()
    print('主进程开放临界区')


if __name__ == '__main__':
    main_thread()
'''
这个小程序主要是体现控制程序执行的先后顺序,如果程序里不加e.set(),主进程和子进程同时执行,主进程中那两个print
瞬间就打印出来(倒数第一行和倒数第四行),子进程也很快就运行,子进程中那两句话也很快会打印,那现在加上了e.set()事件
,主进程就会先打印倒数第四行,子进程先打印另个print,然后两者之间都阻塞了,因为他们都在等待主进程设置事件,
'''

打印结果:

主进程在忙碌的操作临界区
process2要等主进程操作完我才能操作
Process1要等主进程操作完我才能操作
我等不了了,去干别的 False
主进程开放临界区

终于操作完了,该我了 True

前三句话先打印,两秒钟后打印我等不了了,再过一秒打印主进程开放临界区,第一个子进程终于操作完了,该我了。

进程间同步互斥方法2

Lock

同步和互斥主要是保护你的临界资源,当你一个进程操作临界资源的时候,不允许其他进程操作临界资源。Lock的工作原理如下,更直接的进行互斥,上面讲的Event方法更方便控制流程。


已知有进程AB和临界资源C,进程AB同时对临界资源C进行访问,虽然是同时访问,但是肯定有快慢,假设A进程率先访问到了,并且给临界资源上了锁,那么后到的进程B就无法访问,直到A进程用完临界资源并且解锁后,B进程才能对临界资源进行访问,当然B进程访问的时候也会上锁。

这块要注意的是:

     进程A抢占到临界资源C,这个时候A就应该上锁了,进程A操作资源C的这段代码就是临界区,A进程上锁需要加一个acquire函数,这个时候B再要访问就无法访问,他访问不了的原因是,B对资源C进行访问的代码里也要写acquire这个函数,他才会判断这个资源已经被进程A上锁了,所以B进程再上锁就会阻塞,就访问不了 

     如果多个进程协同操作临界资源,只有一个进程写了加锁解锁,这样四根本不管用的,必须是所有进程都对这个临界资源操作加锁解锁,才是管用的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值