1、程序工作原理

进程的限制:每一个时刻只能有一个线程来工作。
多进程的优点:同时利用多个cpu,能够同时进行多个操作。缺点:对内存消耗比较高
当进程数多于cpu数量的时候会导致不能被调用,进程不是越多越好,cpu与进程数量相等最好
线程:java和C# 对于一个进程里面的多个线程,cpu都在同一个时刻能使用。py同一时刻只能调用一个。
so:对于型的应用,py效率较java C#低。
多线程优点:共享进程的内存,可以创造并发操作。缺点:抢占资源,
多线程得时候系统在调用的时候需要记录请求上下文的信息,请求上下文的切换 这个过程非常耗时。因此 线程不是越多越好,具体案例具体分析。
在计算机中,执行任务的最小单元就是线程
IO操作不利用CPU,IO密集型操作适合多线程,对于计算密集型适合多进程
GIL:全局解释器锁,PY特有它会在每个进程上加个锁
系统存在进程和线程的目的是为了提高效率
1.1、单进程单线程
1.2、自定义线程:
主进程
主线程
子线程
2、线程锁 threading.RLock和threading.Lock

多线程修改一个数据得时候可能会造成咱数据。建议使用rlock

3、线程时间:threading.Event: 通知
当有进程间的通讯的情况下这个才有应用场景。汽车类比线程,Event.wait()红灯,Event.set()绿灯,Event.clear():使红灯变绿

even是线程间的通讯机制。Event.wait([timeout]):赌赛线程,知道event对象内部标示位被设置为True或超时时间。Event.set():将标识位设为True。Event.clear():标识位设为False。Event.isSet():判断标识位是否为True。

4、queue模块:生产者-消费者模型

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import queue
import threading
# import queue# q = queue.Queue(maxsize=0)  # 构造一个先进显出队列,maxsize指定队列长度,为0 时,表示队列长度无限制。
#
# q.join()    # 等到队列为空的时候,在执行别的操作
# q.qsize()   # 返回队列的大小 (不可靠)
# q.empty()   # 当队列为空的时候,返回True 否则返回False (不可靠)
# q.full()    # 当队列满的时候,返回True,否则返回False (不可靠)
# q.put(item, block=True, timeout=None) #  将item放入Queue尾部,item必须存在,可以参数block默认为True,表示当队列满时,会等待队列给出可用位置,
# #                          为False时为非阻塞,此时如果队列已满,会引发queue.Full 异常。 可选参数timeout,表示 会阻塞设置的时间,过后,
# #                           如果队列无法给出放入item的位置,则引发 queue.Full 异常
# q.get(block=True, timeout=None) #   移除并返回队列头部的一个值,可选参数block默认为True,表示获取值的时候,如果队列为空,则阻塞,为False时,不阻塞,
# #                       若此时队列为空,则引发 queue.Empty异常。 可选参数timeout,表示会阻塞设置的时候,过后,如果队列为空,则引发Empty异常。
# q.put_nowait(item) #   等效于 put(item,block=False)
# q.get_nowait() #    等效于 get(item,block=False)
message = queue.Queue(10)def producer(i):print("put:",i)# while True:
    message.put(i)def consumer(i):# while True:msg = message.get()print(msg)for i in range(12):t = threading.Thread(target=producer, args=(i,))t.start()for i in range(10):t = threading.Thread(target=consumer, args=(i,))t.start()
qs = message.qsize()
print("当前消息队列的长度为:%d"%(qs))
print("当前消息队列的长度为:",qs)

queue示例代码

join()方法主线程等待,最多等待时间可以hi设置,eg:t.join(2)

    import threadingdef f0():passdef f1(a1,a2):time.sleep(10)f0()t = threading.Thread(target=f1,args(111,222,))t.setDaemon(True)  #默认false 主线程将等待执行完成后结束,设置为true后主线程将不在等待
    t.start()t = threading.Thread(target=f1,args(111,222,))t.start()t = threading.Thread(target=f1,args(111,222,))t.start()t = threading.Thread(target=f1,args(111,222,))t.start()

threading demo

5、进程 :multiprocess是py进程模块

进程之间默认是隔离得,线程的资源默认是共享的

两个进程共享数据需要使用特殊得对象: array:其他语音 或manager.dict()

进程不是,越多越好,建议使用线程池来控制。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from multiprocessing import Pool
import time
def myFun(i):time.sleep(2)return i+100def end_call(arg):print("end_call",arg)# print(p.map(myFun,range(10)))
if __name__ == "__main__":p = Pool(5)for i in range(10):p.apply_async(func=myFun,args=(i,),callback=end_call)print("end")p.close()p.join()

porcesspooldemo

#!/usr/bin/env python
# -*- coding:utf-8 -*-from multiprocessing import  Pool
import timedef f1(a):time.sleep(1)print(a)return 1000
def f2(arg):print(arg)if __name__ =="__main__":pool = Pool(5)for i in range(50):pool.apply_async(func=f1, args=(i,),callback=f2)# pool.apply(func=f1, args=(i,))print('<<=================>>')pool.close()pool.join()

processpooldemo2

6、线程池py没有提供,我们需要自己编写

简单线程池示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import queue
import threading
import timeclass ThreadPool(object):def __init__(self, max_num=20):self.queue = queue.Queue(max_num)for i in range(max_num):self.queue.put(threading.Thread)def get_thread(self):return self.queue.get()def add_thread(self):self.queue.put(threading.Thread)def func(pool,a1):time.sleep(2)print(a1)pool.add_thread()p = ThreadPool(10)for i in range(100):#获得类thread = p.get_thread()#对象 = 类()#
    t = thread(target=func,args=(p,i,))t.start()
"""
pool = ThreadPool(10)def func(arg, p):print argimport timetime.sleep(2)p.add_thread()for i in xrange(30):thread = pool.get_thread()t = thread(target=func, args=(i, pool))t.start()
"""# p = ThreadPool()
# ret = p.get_thread()
#
# t = ret(target=func,)
# t.start()

View Code

复杂的线城池示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-import queue
import threading
import contextlib
import timeStopEvent = object()class ThreadPool(object):def __init__(self, max_num, max_task_num = None):if max_task_num:self.q = queue.Queue(max_task_num)else:self.q = queue.Queue()# 多大容量self.max_num = max_numself.cancel = Falseself.terminal = False# 真实创建的线程列表self.generate_list = []# 空闲线程数量self.free_list = []def run(self, func, args, callback=None):"""线程池执行一个任务:param func: 任务函数:param args: 任务函数所需参数:param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数):return: 如果线程池已经终止,则返回True否则None"""if self.cancel:returnif len(self.free_list) == 0 and len(self.generate_list) < self.max_num:self.generate_thread()w = (func, args, callback,)self.q.put(w)def generate_thread(self):"""创建一个线程"""t = threading.Thread(target=self.call)t.start()def call(self):"""循环去获取任务函数并执行任务函数"""# 获取当前进程current_thread = threading.currentThread()self.generate_list.append(current_thread)# 取任务event = self.q.get()while event != StopEvent:# 是元组=》是任务# 解开任务包# 执行任务
func, arguments, callback = eventtry:result = func(*arguments)success = Trueexcept Exception as e:success = Falseresult = Noneif callback is not None:try:callback(success, result)except Exception as e:passwith self.worker_state(self.free_list, current_thread):if self.terminal:event = StopEventelse:event = self.q.get()else:# 不是元组,不是任务# 标记:我空闲了# 执行后线程死掉
            self.generate_list.remove(current_thread)def close(self):"""执行完所有的任务后,所有线程停止"""self.cancel = Truefull_size = len(self.generate_list)while full_size:self.q.put(StopEvent)full_size -= 1def terminate(self):"""无论是否还有任务,终止线程"""self.terminal = Truewhile self.generate_list:self.q.put(StopEvent)self.q.empty()@contextlib.contextmanagerdef worker_state(self, state_list, worker_thread):"""用于记录线程中正在等待的线程数"""state_list.append(worker_thread)try:yieldfinally:state_list.remove(worker_thread)# How to use
pool = ThreadPool(5)def callback(status, result):# status, execute action status# result, execute action return valuepassdef action(i):print(i)for i in range(30):#将任务放在队列#着手开始处理任务#创建线程(有空闲线程则不创建;不高于线程池的限制;根据任务个数判断)  =》线程去队列中去任务ret = pool.run(action, (i,), callback)time.sleep(5)
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
# pool.close()
# pool.terminate()

View Code

7、上下文管理:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  queue
import  contextlib
"""
q = queue.Queue()
li = []# li.append(1)
# q.get()
# li.remove(1)@contextlib.contextmanager
def worker_stater(xxx,val):xxx.append(val)try:yield 123finally:xxx.remove(val)q.put("john")
with worker_stater(li,1) as f:print('before',li)print(f)q.get()passpassprint('after',li)
"""@contextlib.contextmanager
def myopen(file_path,mode):f = open(file_path,mode,encoding='utf-8')try:yield  ffinally:f.close()with myopen('index.html','r') as file_obj:print(file_obj.readline())

demo

8、协程:

协程主要应用在IO密集型场景,由程序来控制,也叫微线程,高性能通常与协程挂钩

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  geventdef foo():print('Running in foo')gevent.sleep(0)  #切换协程print('Explicit context switch to foo agein')
def bar():print('Running in bar')gevent.sleep(0)  #切换协程print('Explicit context switch back to bar agein')gevent.joinall([gevent.spawn(foo),gevent.spawn(bar),
])

demo1

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from gevent import  monkey;monkey.patch_all()
import  gevent
import  requestsdef f(url):print('GET:%s' % url)resp = requests.get(url)data = resp.textprint(url,len(data))gevent.joinall([gevent.spawn(f,'http://www.python.org/'),gevent.spawn(f,'https://www.yahoo.com/'),gevent.spawn(f,'https://github.com/'),
])

demo2

#!/usr/bin/env python
# -*- coding:utf-8 -*-from greenlet import  greenletdef test1():print(12)gr2.switch()print(34)gr2.switch()def test2():print(56)gr1.switch()print(78)gr1.switch()gr1 = greenlet(test1)
gr2 = greenlet(test2)gr1.switch()

demo3

end

转载于:https://www.cnblogs.com/workherd/p/8809764.html

day212223:线程、进程、协程相关推荐

  1. 打开线程 | 进程 | 协程的大门

    不知从几何起,可能是大三那年的操作系统考试,也可能是刚经历完的秋招,这些概念总是迷迷糊糊,可能自己回答的和其他人的答复也差不多,并没有什么亮点,通常都会以:「我们换个题」的方式结束,有时候也挺尴尬的. ...

  2. python线程进程协程面试_Python学习经验之谈:关于协程的理解和其相关面试问题...

    都知道Python非常适合初学者学习来入门编程,昨天有伙伴留言说面试了Python岗位,问及了一个关于协程的问题,想了想还是跟大家出一篇协程相关的文章和在Python面试中可能会问及的相关面试问题.都 ...

  3. python协程和线程_python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...

  4. python apply_async死锁_python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是不 ...

  5. python_21_线程+进程+协程

    python_线程_进程_协程 什么是线程? -- os能够进行运算调度的最小单位,被包含在进程之中,是一串指令的集合 -- 每个线程都是独立的,可以访问同一进程下所有的资源 什么是进程? -- 每个 ...

  6. 十四丶并发编程(线程 进程 协程)

    Yuan先生 知识预览 操作系统 回到顶部 操作系统 一 为什么要有操作系统? 现代计算机系统是由一个或者多个处理器,主存,磁盘,打印机,键盘,鼠标显示器,网络接口以及各种其他输入输出设备组成的复杂系 ...

  7. 进程 线程 协程_进程,线程,协程那些事

    无论我们写出怎样的程序,最后都是由操作系统来运行我们的程序,而操作系统如何管理我们的程序,我们程序的数据如何保存和计算,这些都是操作系统需要处理的事情,我们只要将写好的程序交给操作系统就好. 虽然操作 ...

  8. python 多线程和协程结合_一文讲透 “进程、线程、协程”

    本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什么? 为什么说Python中的多线程是伪多线程? 不同的应用场景该如何选择技术方案? ... 什么是进程 ...

  9. 进程、线程、协程、通信方式

    文章目录 进程 线程 协程 进程.线程.协程的区别 概念 进程.线程共同点 进程.线程不同点 线程.协程比较 通信方式之间的差异 进程通信 管道(pipe) 有名管道 (namedpipe) 信号量( ...

  10. 什么是 “进程、线程、协程”?

    作者 | 头文件 责编 | 王晓曼 来源 | 程序员小灰(ID:chengxuyuanxiaohui) 本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什 ...

最新文章

  1. AI之父图灵登上50英镑钞票,荣耀比肩牛顿达尔文;吴恩达:将激励更多人
  2. 和尚挖井故事给程序员的启示!
  3. 内存常用的页面调度算法
  4. 如何检查防火墙引起的端口不通
  5. Python全局变量和局部变量
  6. mapper 判断条件为null
  7. asp留言板源码-XYCMS留言板 v8.0
  8. Josephus问题的Java解决方法
  9. java:eclipse:windows开发环境log4j系统找不到指定的路径
  10. 探讨【IGE】的源代码【五】。
  11. ajax实现文件上传6,实现Ajax文件上传功能
  12. wgs84坐标系和国内地图坐标系的转换
  13. 路由器和带宽猫、AP、AC、交换机
  14. leetcode 714. 买卖股票的时机含手续费 python
  15. 马赛克(蒙太奇)图片生成--Python实现
  16. Windows使用ssh登入mac
  17. 从0使用Ruby on Rails打造企业级RESTful API项目实战之我的云音乐
  18. 手机通过adb工具安装应用
  19. 斐讯dc1服务器什么时候修复,[4月1日更新!!]斐讯DC1插座自制固件接入ha
  20. 互联网开发搞手游创作8-再次推倒重新

热门文章

  1. 垂直梯形校正画质损失多少_投影小常识 梯形矫正竟会影响清晰度
  2. 北理计算机网络实验汇编,北理计算机与网络实验(II)(汇编语言实验4).docx
  3. 用awk一些常用技巧sort uniq
  4. Pytorch(3)-数据载入接口:Dataloader、datasets
  5. 《剑指Offer》52:两个链表的第一个公共节点
  6. 2000年考研英语阅读理解文章五
  7. macos 10.15 django2.2+apache2.4+ladon+wsgi写webseverice接口
  8. 深度卷积神经网络CNNs的多GPU并行框架及其应用
  9. 软件开发人员进修必备的20本书
  10. AMD Mantle再添新作,引发下代GPU架构猜想