进程间通信

进程间通讯有多种方式,包括信号,管道,消息队列等
进程间通信我们可以用Queue
Queue有两个方法:
Put方法:以插入数据到队列中,他还有两个可选参数:blocked和timeout。详情自行百度
Get方法:从队列读取并且删除一个元素。同样,他还有两个可选参数:blocked和timeout。详情自行百度
from multiprocessing import Process,Queuesign_done = '__flag_done'     #初始化一个变量用来判断数据def woke(queue):for i in range(8):queue.put(i)print('往队列里面添加数据{}'.format(i))queue.put(sign_done)def read(queue):while 1:num = queue.get(True)if num == '__flag_done':print('down')breakprint('从队列里面获取%s' % num)if __name__ == '__main__':duilie = Queue()        #构造队列t1 = Process(target=woke,args=(duilie,))t2 = Process(target=read,args=(duilie,))t1.start()t2.start()t1.join()t2.join()print('主进程执行完毕')线程间通信:线程间通信有两种方法1.也可以用Queue2.event先看第一种:from queue import Queuefrom threading import Threadimport time,randomshatdown = object()def witer(out_q):for num in range(10):date = random.randint(1,10)out_q.put(date)print('添加数据{}'.format(date))time.sleep(0.2)out_q.put(shatdown)def rade(in_q):while True:data = in_q.get()if data is shatdown:in_q.put(data)breakelse:print('获取数据{}'.format(data))time.sleep(0.3)q = Queue()t1 = Thread(target=rade,args=(q,))t2 = Thread(target=witer,args=(q,))t1.start()t2.start()t1.join()第二种event:用 threading.Event 实现线程间通信使用threading.Event可以使一个线程等待其他线程的通知,我们把这个Event传递到线程对象中,Event默认内置了一个标志,初始值为False。一旦该线程通过wait()方法进入等待状态,直到另一个线程调用该Event的set()方法将内置标志设置为True时,该Event会通知所有等待状态的线程恢复运行。import threading,timeclass Myfunc(threading.Thread):def __init__(self,single,name):threading.Thread.__init__(self,name = name)self.single = singledef run(self):print('我是{}生产线,现在没钱了,只能停工'.format(self.name))self.single.wait()print('筹到钱了,{}开始开工'.format(self.name))if __name__ == '__main__':single = threading.Event()print("这是一个服装生产线,现在3万元启动资金,需要生产3中服装,但资金不足,只能先开工""如果老板筹不到钱只能将进行中的业务暂时停止,直到有钱!")for i in ['衬衣','羽绒服','裤子']:p = Myfunc(single,i)p.start()print('老板筹钱中')time.sleep(3)print('老板筹到钱啦')single.set()   #继续往下执行

死锁

所谓死锁: 是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,
若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。1.在多线程中,不可避免的一个问题,就是全局变量资源存在着被多个线程调用的问题,在调用的过程中就存在着资源竞争2.这种资源竞争是如何产生的呢?
# 举例: 在一个线程中执行任务需要同时使用两个以上资源,修改资源时都要获取对应的资源锁A = 0B = 0import threadingmax_a = threading.Lock()    #创建锁min_b = threading.Lock()    #创建锁import threadingclass Myfunc(threading.Thread):def __init__(self):threading.Thread.__init__(self)def run(self):        #run方法,只要start就会执行这个方法self.fun1()self.fun2()def fun1(self):global max_a,min_bif max_a.acquire():      #锁定print('我是线程{},获取资源{}'.format(self.name,'A'))if min_b.acquire():print('我是线程{},获取资源{}'.format(self.name,'B'))max_a.release()    #释放资源def fun2(self):global max_a,min_bif min_b.acquire():print('我是线程{},获取资源{}'.format(self.name,'B'))if max_a.acquire():print('我是线程{},获取资源{}'.format(self.name, 'A'))min_b.ralease()if __name__ == '__main__':for i in range(100):     #循环100次t1 = Myfunc()t1.start()      上述代码,当线程执行次数有限时,全局资源不会发生大的变化,但是当高并发时,就会产生资源竞争问题

嵌套死锁

如果一个线程遇到锁嵌套的情况该怎么办,这个嵌套是指当我一个线程在获取临界资源时,又需要再次获取。import threadingimport time
#count = threading.RLock()
count = threading.Lock()
a = 0
class Myfunc(threading.Thread):def __init__(self):threading.Thread.__init__(self)def run(self):global count,aif count.acquire(1):  #0 就是 False 代表不阻塞   1代表True  代表阻塞# 默认为true,会等待,如果是false,就不等待,结果是没拿到锁a+=1print('{}'.format(self.name,count))if count.acquire():a-=1print('{}'.format(self.name,count))count.release()count.release()
if __name__ == '__main__':for i in range(3):t1 = Myfunc()t1.start()
# python提供了“可重入锁”:threading.RLock。
# 这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,
# 从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。
# 使用RLock代替上面例子中的Lock,则不会产生死锁

线程池

 描述:线程池是维护工作线程池以并行执行耗时操作的对象。它通过将作业放入工作请求队列中来为作业分配作业,然后由下一个可用的线程拾取它们。然后,它在后台执行请求的操作,并将结果放入另一个队列。然后,线程池对象可以在它们可用时或在所有线程完成其工作之后立即从该队列中的所有线程收集结果。然后可以定义回调来处理每个结果。[详情见官方文档](https://chrisarndt.de/projects/threadpool/)优点:(1)可以控制产生线程的数量。通过预先创建一定数量的工作线程并限制其数量,控制线程对象的内存消耗。(2)降低系统开销和资源消耗。通过对多个请求重用线程,线程创建、销毁的开销被分摊到了多个请求上。另外通过限制线程数量,降低虚拟机在垃圾回收方面的开销。(3)提高系统响应速度。线程事先已被创建,请求到达时可直接进行处理,消除了因线程创建所带来的延迟,另外多个线程可并发处理。 线程池的基本实现方法:(1)线程池管理器。创建并维护线程池,根据需要调整池的大小,并监控线程泄漏现象。(2)工作线程。它是一个可以循环执行任务的线程,没有任务时处于 Wait 状态,新任务到达时可被唤醒。(3)任务队列。它提供一种缓冲机制,用以临时存放待处理的任务,同时作为并发线程的 monitor 对象。(4)任务接口。它是每个任务必须实现的接口,工作线程通过该接口调度任务的执行。构建线程池管理器时,首先初始化任务队列(Queue),运行时通过调用添加任务的方法将任务添加到任务队列中。之后创建并启动一定数量的工作线程,将这些线程保存在线程队列中。线程池管理器在运行时可根据需要增加或减少工作线程数量。工作线程运行时首先锁定任务队列,以保证多线程对任务队列的正确并发访问,如队列中有待处理的任务,工作线程取走一个任务并释放对任务队列的锁定,以便其他线程实现对任务队列的访问和处理。在获取任务之后工作线程调用任务接口完成对任务的处理。当任务队列为空时,工作线程加入到任务队列的等待线程列表中,此时工作线程处于 Wait 状态,几乎不占 CPU 资源。一旦新的任务到达,通过调用任务列表对象的notify方法,从等待线程列表中唤醒一个工作线程以对任务进行处理。通过这种协作模式,既节省了线程创建、销毁的开销,又保证了对任务的并发处理,提高了系统的响应速度。简而言之:就是把并发执行的任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程。只要池里有空闲的线程,任务就会分配给一个线程执行。from multiprocessing.pool import ThreadPool   #线程池def f(n):print(sum(range(1,1000)))if __name__ == '__main__':p = ThreadPool(5)     #池的最大进程数for i in range(5):p.apply_async(func=f,args=(20,))p.close()   #不在接受新的请求p.join()

python之进程和线程(二)相关推荐

  1. Python创建进程、线程的两种方式

    代码创建进程和线程的两种方式 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识. ...

  2. Python【进程和线程】保姆式教学,1个台机子多只手干活的秘籍

    进程线程有多重要?刚开始学Python的时候你可能还没有感觉到,因为你写的代码从上到下执行一遍就可以了,但实际上这很初级,实际开发写项目的时候,为了充分利用电脑配置来加快程序进度,我们往往会用到多进程 ...

  3. python之进程和线程的对比

    python之进程和线程的对比 1. 进程和线程的对比的三个方向 关系对比 区别对比 优缺点对比 2. 关系对比 线程是依附在进程里面的,没有进程就没有线程. 一个进程默认提供一条线程,进程可以创建多 ...

  4. 二十二、 深入Python的进程和线程(上篇)

    @Author: Runsen 进程(Process)和线程(Thread)都是操作系统中的基本概念,它们之间有一些优劣和差异,那么在Python中如何使用进程和线程? 文章目录 CPU 进程 线程 ...

  5. 《Python》进程收尾线程初识

    一.数据共享 from multiprocessing import Manager 把所有实现了数据共享的比较便捷的类都重新又封装了一遍,并且在原有的multiprocessing基础上增加了新的机 ...

  6. python爬虫进程和线程的区别_熬了两个通宵写的!终于把多线程和多进程彻底讲明白了!...

    我们知道,在一台计算机中,我们可以同时打开许多软件,比如同时浏览网页.听音乐.打字等等,看似非常正常.但仔细想想,为什么计算机可以做到这么多软件同时运行呢?这就涉及到计算机中的两个重要概念:多进程和多 ...

  7. python之进程与线程

    什么是操作系统       可能很多人都会说,我们平时装的windows7 windows10都是操作系统,没错,他们都是操作系统.还有没有其他的? 想想我们使用的手机,Google公司的Androi ...

  8. Python高级系列教程:Python的进程和线程

    学习目标 1.了解多任务的概念 2.了解进程的概念以及多进程的作用 3.掌握多进程完成多任务的工作原理及案例编写 4.掌握进程编号的获取方式以及进程使用的注意事项 5.了解线程的概念以及多线程的作用 ...

  9. python之进程和线程2

    1  GIL全局解释器锁定义 定义:在一个线程拥有了解释器的访问权后,其他的所有线程都必须等待他释放解释器的访问权,即这些线程的下一条指令并不会互相影响. 缺点:多处理器退化为单处理器 优点:避免大量 ...

  10. python爬虫进程和线程_python爬虫番外篇(一)进程,线程的初步了解-阿里云开发者社区...

    整理这番外篇的原因是希望能够让爬虫的朋友更加理解这块内容,因为爬虫爬取数据可能很简单,但是如何高效持久的爬,利用进程,线程,以及异步IO,其实很多人和我一样,故整理此系列番外篇 一.进程 程序并不能单 ...

最新文章

  1. 正则表达式匹配不包含特定字符串解决匹配溢出问题
  2. 数据中心安全的六条黄金规则
  3. 2019 WAIC | 腾讯张正友:人工智能的热与酷
  4. Sharepoint学习笔记—ECM系列--4 根据位置设置的默认元数据值(Location-Based Metadata Defaults)
  5. springcloud 入门 4 (rebbon源码解读)
  6. leetcode题解976-三角形的最大周长
  7. 一次线上事故,让我对MySql的时间戳存char(10)还是int(10)有了全新的认识
  8. 转:神奇的Fastcgi_Finish_Request
  9. 【Demo 0015】坐标系
  10. win10下安装Ubuntu18.4双系统(适合小白)
  11. Linux中的 【 find 】 命令
  12. C语言形参和实参以及C#中的ref
  13. 个人用户可以向运营商申请短信接口吗?
  14. RabbitMQ-KeepLive
  15. ubuntu18下查看opencv版本、多版本之间的共存,切换、下载地址
  16. 如何打开RAR文件?
  17. 李智慧 - 架构师训练营总览
  18. 离了加多宝 第三季好声音将“变味”
  19. php仿淘宝课程设计任务书
  20. Elasticsearch 入门(1):基本概念,安装教程,索引的创建,查询,删除,主键查询,修改,添加,聚合查询,条件查询

热门文章

  1. 常见的http面试问题
  2. bullet物理系统功能及实现简介
  3. HTML技能点--表单enctype属性解释
  4. 基于 jsp + servlet + Mysql 实现 网上书店购物系统 (源码)
  5. 分享一个新手从 0 到 1 的知乎好物操作过程
  6. Bigtable: A Distributed Storage System for Structured Data
  7. flink性能测试 (工业领域三维空间数据的重要性)
  8. 报表控件ActiveReports设计器,让报表开发更简单
  9. 【数学1】基础数学问题 - 题单 - 洛谷
  10. frame框架实现诗词页面