day35 守护进程、互斥锁、IPC

1、守护进程

  1. # 守护进程:当父进程执行完毕后,设置的守护进程也会跟着结束
    # 当一个进程被设置为守护进程后,其不能再产生子进程
  1. from multiprocessing import Process
  2. import time

  3. def test():
  4. print("妃子入宫了")
  5. time.sleep(5)
  6. print("子进程挂了")

  7. if __name__ == '__main__':
  8. p = Process(target=test)
  9. p.daemon = True
  10. p.start()
  11. time.sleep(3)
  12. print("父进程挂了")
  13.  
  14. # 妃子入宫了
  15. # 父进程挂了
  1.  

2、互斥锁

  1. # 在进行打印操作时,如果三个全部进行打印操作就会互相影响打印结果
    # 所以此时需要将打印操作设置为串行
    #使用join方法可以将优先级进行提升,但是这样执行顺序就固定了,就不能使每个子进程公平竞争CPU
    # 如果按照下方的程序进行处理,那么这样就没有开启子进程的意义了
  1. def test():
  2. print("i am li")
  3. time.sleep(random.random())
  4. print("my age is 15")
  5. time.sleep(random.random())
  6. print("i am a boy")

  7. def test2():
  8. print("i am lee")
  9. time.sleep(random.random())
  10. print("my age is 20")
  11. time.sleep(random.random())
  12. print("i am a girl")

  13. def test3():
  14. print("i am wu")
  15. time.sleep(random.random())
  16. print("my age is 25")
  17. time.sleep(random.random())
  18. print("i am a man")


  19. if __name__ == '__main__':
  20. p = multiprocessing.Process(target=test)
  21. p1 = multiprocessing.Process(target=test3)
  22. p2 = multiprocessing.Process(target=test2)
  23. p.start()
  24. p.join()
  25. p1.start()
  26. p1.join()
  27. p2.start()
  28. p2.join()
  29.  
  30. # i am li
  31. # my age is 15
  32. # i am a boy
  33. # i am lee
  34. # my age is 20
  35. # i am a girl
  36. # i am wu
  37. # my age is 25
  38. # i am a man
  1. # 使用互斥锁
    # lock = Lock()
    # 注意:互斥锁不能在全部变量中进行设置,这是因为子进程在进行设置时,会导入父进程的代码,
    # 只有放在if __name__ == "__main__"中确保使用的是同一把锁

    # 使用join与互斥锁的区别:
    # 1、join会人为的打乱子进程的优先级,从而使某个子进程首先执行完,打乱了公平竞争
    # 2、join只能将整个函数的优先级进行提高,不能对其中的某一行进行操作
    #   互斥锁可以直接对函数中的某一行代码进行操作,这样在进行程序的执行时,可以提高程序的执行效率
    #   这种又称之为粒度,粒度越小,执行效率越高,粒度越大执行效率越低


    # 实际上,互斥锁不是锁住的文件或者共享资源,
    # 而是在共享内存中增加一个标志,当碰到Lock对象时就会去全局变量中访问这个标志,如果这个标志为True就会执行acquire方法,将共享空间中的标志改为False
    # 如果标志为False就不能执行这段代码,直到等到更改这个变量的对象再次访问全局变量,并使用release方法将这个标志重新改为True,其余进程才能访问并更改这个标志
  1. def test(lock):
  2. lock.acquire()
  3. print("i am li")
  4. time.sleep(random.random())
  5. print("my age is 15")
  6. time.sleep(random.random())
  7. print("i am a boy")
  8. lock.release()

  9. def test2(lock):
  10. lock.acquire()
  11. print("i am lee")
  12. time.sleep(random.random())
  13. print("my age is 20")
  14. time.sleep(random.random())
  15. print("i am a girl")
  16. lock.release()

  17. def test3(lock):
  18. lock.acquire()
  19. print("i am wu")
  20. time.sleep(random.random())
  21. print("my age is 25")
  22. time.sleep(random.random())
  23. print("i am a man")
  24. lock.release()


  25. if __name__ == '__main__':
  26. lock = Lock()
  27. p = multiprocessing.Process(target=test,args=(lock,))
  28. p1 = multiprocessing.Process(target=test3,args=(lock,))
  29. p2 = multiprocessing.Process(target=test2,args=(lock,))

  30. p.start()
  31. p1.start()
  32. p2.start()
  33.  
  34. # i am li
  35. # my age is 15
  36. # i am a boy
  37. # i am wu
  38. # my age is 25
  39. # i am a man
  40. # i am lee
  41. # my age is 20
  42. # i am a girl

3、互斥锁的应用

  1. import multiprocessing
  2. from multiprocessing import Lock
  3. import time
  4. import json
  5. import random

  6. def show_ticket(i):
  7. time.sleep(random.random())
  8. with open("aa.json","rt",encoding="utf-8") as f:
  9. num_dic = json.load(f)
  10. time.sleep(random.random())
  11. print("%s正在查看余票,余票数量为%s"%(i,num_dic["num"]))
  12. return num_dic["num"]

  13. def buy_ticket(i):
  14. time.sleep(random.random())
  15. with open("aa.json","rt",encoding="utf-8") as f:
  16. num_dic = json.load(f)
  17. ticket_num = num_dic["num"]
  18. if ticket_num > 0:
  19. time.sleep(random.random())
  20. ticket_num -= 1
  21. num_dic["num"] = ticket_num
  22. print("%s抢票成功"%i)
  23. with open("aa.json","wt",encoding="utf-8") as f:
  24. print(num_dic)
  25. json.dump(num_dic,f)
  26. else:
  27. print("%s余票数量为%s,抢票失败"%(i,ticket_num))


  28. def run(i,lock):
  29. show_ticket(i)
  30. lock.acquire()
  31. buy_ticket(i)
  32. lock.release()

  33. if __name__ == '__main__':
  34. lock = Lock()
  35. for i in range(10):
  36. p = multiprocessing.Process(target=run,args=[i,lock])
  37. p.start()
  38. # 执行结果为:
  39.  
  40. # 1正在查看余票,余票数量为1
  41. # 0正在查看余票,余票数量为1
  42. # 4正在查看余票,余票数量为1
  43. # 3正在查看余票,余票数量为1
  44. # 6正在查看余票,余票数量为1
  45. # 5正在查看余票,余票数量为1
  46. # 8正在查看余票,余票数量为1
  47. # 2正在查看余票,余票数量为1
  48. # 7正在查看余票,余票数量为1
  49. # 1抢票成功
  50. # {'num': 0}
  51. # 0余票数量为0,抢票失败
  52. # 9正在查看余票,余票数量为1
  53. # 4余票数量为0,抢票失败
  54. # 3余票数量为0,抢票失败
  55. # 6余票数量为0,抢票失败
  56. # 5余票数量为0,抢票失败
  57. # 8余票数量为0,抢票失败
  58. # 2余票数量为0,抢票失败
  59. # 7余票数量为0,抢票失败
  60. # 9余票数量为0,抢票失败

4、IPC

  1. # IPC (inter-process communication):进程间通信
    # 在内存中,进程间的内存是相互独立的,如果想要使用其他进程中的数据此时需要进程间的通信
    # 实现进程间通信的方式:
    # 1、使用共享文件
    # 2、使用共享内存
    # 3、使用管道
    # 4、使用队列

    # 使用共享文件进行进程间通信:由于文件存在于硬盘中,使用该方法进行通信效率较低,较耗时
    # 使用subprocess管道进行进程间通信:管道只能进行单向的进程通信
    # 使用共享内存进行进程间通信

    # 使用共享内存的方法进行进程间通信,由于进程访问的是同一个数据,所以需要加互斥锁,如果不加将会影响数据的安全性
    # 在父进程中设置共享内存的内容,如果父进程在子进程还执行时结束,那么就会报错,此时必须设置join方法使父进程在子进程结束后再结束
    # 由于使用互斥锁存在死锁的问题,所有尽量少使用这种方式实现进程间通信
  1. from multiprocessing import Manager,Lock
  2. import multiprocessing
  3. import time
  4. import random


  5. def fn(dic,lock):
  6. time.sleep(random.random())
  7. # lock.acquire()
  8. a = dic["a"]
  9. a = a-1
  10. time.sleep(random.random())
  11. dic["a"] = a
  12. # lock.release()
  13. print(dic["a"])

  14. if __name__ == '__main__':
  15. dic = {"a":10}
  16. lock = Lock()
  17. manage = Manager()
  18. data = manage.dict({"a":10})
  19. for i in range(10):
  20. p = multiprocessing.Process(target=fn,args=[data,lock])
  21. p.start()

  22. time.sleep(8)
  23. print(data["a"])
  24. # 使用队列(Queue)实现进程间通信
  25. # 在multiprocessing 中封装了Queue类来通过队列实现进程间的通讯
  26. from multiprocessing import Queue


  27. q = Queue(4)
  28. q.put(1)
  29. q.put(2)
  30. q.put(3)
  31. q.put(4)
  32. q.put(5) # 当在队列创建时设置了队列的最大值,那么当队列中存在的值超过队列的最大值时就会处于阻塞状态,直到队列中的值被取出后剩下的数量少于设置的最大值

  33. print(q.get())
  34. print(q.get())
  35. print(q.get())
  36. print(q.get()) # 当管道中的数据被取出后,进程就会处于阻塞态,等待着队列中添加数据


  1. # q.get及q.put中的其它参数
    # 1、block(阻塞):默认为True,如果设置为False,那么在超出队列最大值,或者队列中的值被取完后还在取值时报错
    # 2、timeout : 只有在block 设置为True时才有效,当设置该值后,在进入阻塞态一段时间后才会报错

5、生产者消费者模型

  1. # 生产者消费者模型

  1. import time
  2. from multiprocessing import Queue,Process
  3. import random
  4. def maker(q):
  5. for i in range(10):
  6. time.sleep(random.random())
  7. print("第%s份食物做好啦..."%i)
  8. q.put(i)


  9. def eater(q):
  10. for t in range(10):
  11. i = q.get()
  12. time.sleep(random.random())
  13. print(" 第%s份食物吃完啦..."%i)

  14. # 在不使用多进程之前,相当于只有一份餐具,我们只能创建一份吃一份食物

  15. # for i in range(10):
  16. # maker(i)
  17. # eater(i)


  18. # 在多进程中,创建食物与吃食物可以一起进行,相当于有好多餐具
  19. if __name__ == '__main__':
  20. q = Queue()
  21. mp = Process(target=maker,args=[q,])
  22. ep = Process(target=eater,args=[q,])
  23. mp.start()
  24. ep.start()
  1.  

day35 守护进程、互斥锁、IPC的更多相关文章

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

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

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

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

  3. 守护模式,互斥锁,IPC通讯,生产者消费者模型

    '''1,什么是生产者消费者模型 生产者:比喻的是程序中负责产生数据的任务 消费者:比喻的是程序中负责处理数据的任务 生产者->共享的介质(队列)<-消费者 2,为何用 实现了生产者与消费 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

    链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...

  2. [AngularJS] Decorator pattern for code reuse

    Imaging you have a large application, inside this large application you have many small individual a ...

  3. .net core Areas区域

    //使用MVC app.UseMvc(routes => { routes.MapRoute( name: "areas", template: "{area:ex ...

  4. React组件间通信-sub/pub机制

    React生命周期第二个demo演示了兄弟组件的通信,需要通过父组件,比较麻烦:下面介绍sub/pub机制来事项组件间通信. 1.导包 npm i pubsub-js 2.UserSearch.jsx ...

  5. CSS3-弹性盒布局(Flex Box)

    弹性盒布局(Flex Box) 一.概念 弹性盒子是 CSS3 的一种新的布局模式. CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型 ...

  6. 21.栈的压入、弹出序列 Java

    题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...

  7. Leetcode题目139.单词拆分(动态规划-中等)

    题目描述: 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆分时可以重复使用字典中的单词.你可以假设字典 ...

  8. js 中null,undefined区别

    首先摘自阮一峰先生的文章: 大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的None,Ruby语言的nil. 有点奇 ...

  9. IDEA Method definition shorthands are not supported by current JavaScript version

    sentinel-dashboard前端用到了AngularJS v1.4.8,在IDEA里修改js,触发js验证时有一些js文件会出现红色波浪线. 在代码行里鼠标一上去提示信息:Method def ...

  10. Trees Made to Order——Catalan数和递归

    Trees Made to Order Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7155   Accepted: 40 ...