进程互斥锁

引入:

  进程之间数据不共享,但是共享同一套文件系统(如硬盘、键盘、cpu等),所以访问同一个文件,或同一个打印终端,是没有问题的,竞争带来的结果就是错乱,如何控制,就是加锁处理,即进程加锁。

 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱
from multiprocessing import Process
import os,time
def work():
print('%s is running' %os.getpid())
time.sleep(2)
print('%s is done' %os.getpid()) if __name__ == '__main__':
for i in range(3):
p=Process(target=work)
p.start() # 并发运行,效率高,但竞争同一打印终端,带来了打印错乱

特点:

  1.某进程先获取到cpu资源之后,要立即上锁,避免其他人对资源的竞争,只有当该进程解锁(释放)之后,剩余的进程才能进行竞争。

  2.进程互斥锁使得程序的执行顺序成为串行,牺牲了效率,但提高了安全性。

  3.同一时刻只允许一个进程运行,其他进程只能等待。(这与后面的信号量相反,信号量允许多个进程同时运行)

代码示例:

 from multiprocessing import Process,Lock
import os,time
def work(lock):
lock.acquire() #上锁
print('%s is running' %os.getpid())
time.sleep(2)
print('%s is done' %os.getpid())
lock.release()#解锁
if __name__ == '__main__':
lock = Lock()#创建一个互斥锁对象
for i in range(3):
p=Process(target=work,args=(lock,))
p.start()

进程互斥锁

互斥锁解决抢票问题:

 from  multiprocessing import Process,Lock
import json
import os
import time
import random def search():
with open('db.txt',encoding='utf-8') as f:#在当前目录创建一个db.txt文件,并写入“ {"count":1} ”
dic=json.load(f)
print('%s 剩余票数 %s' %(os.getpid(),dic['count'])) def get():
with open('db.txt',encoding='utf-8') as read_f:
dic=json.load(read_f) if dic['count'] > 0:
dic['count']-=1
time.sleep(random.randint(1,3)) #模拟手速+网速
with open('db.txt','w',encoding='utf-8') as write_f:
json.dump(dic,write_f)
print('%s 抢票成功' %os.getpid()) def task(mutex):
search()
mutex.acquire()
get()
mutex.release() if __name__ == '__main__':
mutex=Lock()
for i in range(20):
p=Process(target=task,args=(mutex,))
p.start()
p.join()

总结:

  加锁可以保证多个进程修改同一块数据,但是同一时刻只允许一个进程对其修改,其他进程必须等待,即穿行修改,牺牲了效率,但保证了数据的安全性,但如果加锁的步骤增多,又会造成程序的复杂性。

扩展:

  因此我们最好找寻一种解决方案能够兼顾:1、效率高(多个进程共享一块内存的数据)2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。队列和管道都是将数据存放于内存中队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。

进程互斥(锁)------------------>一个坑的更多相关文章

  1. (day29) 进程互斥锁 + 线程

    目录 进程互斥锁 队列和堆栈 进程间通信(IPC) 生产者和消费者模型 线程 什么是线程 为什么使用线程 怎么开启线程 线程对象的属性 线程互斥锁 进程互斥锁 进程间数据不共享,但是共享同一套文件系统 ...

  2. 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发

    子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...

  3. Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信

    Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...

  4. Java使用FileLock实现Java进程互斥锁

    原理:JDK的nio包中FileLock实现类似Linux fcntl的文件锁, 可使文件被进程互斥访问.  借助此功能, 可以实现强大的Java进程互斥锁, 从而在应用层面保证同一时间只有惟一的Ja ...

  5. 守护进程,互斥锁,IPC,队列,生产者与消费者模型

    小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某 ...

  6. 4 并发编程-(进程)-守护进程&互斥锁

    一.守护进程 主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比崇祯皇帝身边的老太监,崇祯皇帝已死老太监就跟着殉葬了. 关于守护进程需要强调两点: 其一:守护进程会在主进程代码执行结束 ...

  7. Python守护进程、进程互斥锁、进程间通信ICP(Queue队列)、生产者消费者模型

    知识点一:守护进程 守护进程:p1.daemon=True 守护进程其实就是一个“子进程“,守护=>伴随 守护进程会伴随主进程的代码运行完毕后而死掉 进程:当父进程需要将一个任务并发出去执行,需 ...

  8. 8.9 day30 并发编程 进程理论 进程方法 守护进程 互斥锁

    多道技术 1.空间上的复用 多个程序共用一套计算机硬件 多道技术原理 2.时间上的复用 ​ 切换+保存状态 ​ 1.当一个程序遇到IO操作 操作系统会剥夺该程序的CPU执行权限( 提高了CPU的利用率 ...

  9. python并发编程-进程理论-进程方法-守护进程-互斥锁-01

    操作系统发展史(主要的几个阶段) 初始系统 1946年第一台计算机诞生,采用手工操作的方式(用穿孔卡片操作) 同一个房间同一时刻只能运行一个程序,效率极低(操作一两个小时,CPU一两秒可能就运算完了) ...

  10. 进程(守护进程--互斥锁--IPC机制--生产者模型--僵尸进程与孤儿进程--模拟抢票--消息队列)

    目录 一:进程理论知识 1.理论知识 二:什么是进程? 三:僵尸进程与孤儿进程 1.僵尸进程 四:守护进程 1.什么是守护进程? 2.主进程创建守护进程 3.守护进程 五:互斥锁(模拟多人抢票) 1. ...

随机推荐

  1. iOS之 Auto Layout

    1. 动画 // 修改从 StoryBoard 绑定到类的约束的值 self.boxView.constant += 80 // 在动画闭包里对其父级进行 layoutIfNeeded() UIVie ...

  2. 用C写的计算运行时间

    #include <stdio.h> #include <stdlib.h> #include <time.h> int main( void ) { long i ...

  3. SQL注入技术

    TalkTalk的信息泄漏事件导致约15万人的敏感信息被暴露,涉嫌造成这一事件的其中一名黑客使用的并不是很新的技术.事实上,该技术的「年纪」比这名15岁黑客还要大两岁. [译注:TalkTalk是英国 ...

  4. 计数排序(O(n+k)的排序算法,空间换时间)

    计数排序就是利用空间换时间,时间复杂度O(n+k) n是元素个数,k是最大数的个数: 统计每个数比他小的有多少,比如比a[i]小的有x个,那么a[i]应该排在x+1的位置 代码: /* * @Auth ...

  5. vue-cli 前端开发,后台接口跨域代理调试问题

    使用 webpack的方式开发的时候,前台开发过程中需要调用很多后台的数据接口,但是通常前后台分离的开发方式,后台的接口数据很可能是不方便或者是不能在前端同学的电脑上运行的,也就出现了所谓的跨域问题. ...

  6. 几种文件查找命令,whereis ,find ,locate.

    whereis对于文件的查找,是将系统内的所有文件放在一个数据库文件里.whereis 和 locate 都是以该数据库为准的(由于每个数据库会有一个更新时间,一般在更新时间之后才可以找到).而fin ...

  7. java.io.File类操作

    一.java.io.File类 String path="E:/222/aaa";//路径 String path1="aaa.txt"; File file= ...

  8. EF分页

    先来看看几个LINQ to SQL的几个函数. Take 说明:获取集合的前n个元素:延迟.即只返回限定数量的结果集. var q = (  from e in db.Employees  order ...

  9. python的Windows下的安装

    1.先打开网址http://www.python.org/download/: 2.在下载列表中选择Window平台安装包, 找到最后 web-based installer 是需要通过联网完成安装的 ...

  10. bzoj1003

    考虑dp[i]表示前i天的最小总成本. 枚举上一次在第j天之后对路线进行了修改,那么就由dp[j]转移至dp[i],转移的代价是把第[j+1,i]天所有被占用的点全删掉后的最短路(不连通当然就是INF ...