day212223:线程、进程、协程

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php课程 8-28 php如何绘制生成显示图片

php课程 8-28 php如何绘制生成显示图片 一、总结 一句话总结&#xff1a;gd库轻松解决 1、php图片操作生成的图的两种去向是什么&#xff1f; 一种在页面直接输出&#xff0c;一种存进本地磁盘 2、php操作图片的库有哪些&#xff1f; PHP: Image Processing and Generation - M…

flavr—超级漂亮的jQuery扁平弹出对话框

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 插件描述&#xff1a;flavr是一个时尚的扁平弹出对话框为您的下一个网站。 flavr是响应设计布局&#xff0c;能够适应任何屏幕大小。 得…

经纬度之间的距离计算

来自谷歌地图的计算公式&#xff1a; 通过JAVA的Math类各种方法调用。实现上述公式 private static double EARTH_RADIUS 6378.137;// 单位千米/*** 角度弧度计算公式 rad:(). <br/>* * 360度2π πMath.PI* * x度 x*π/360 弧度* * author chiwei* param d* return* s…

在CentOS7阿里云服务器部署ThinkPHP5,并配置phpstrom实现同步开发(微信小程序及管理员后端)...

小程序和后端同步开发 1.服务器安装tp5框架&#xff1a; 方法很多比如&#xff1a;github、linux命令直接手动下、composer 都可以&#xff0c;方法很多&#xff0c;百度一下&#xff0c;不再累述 2.这时你会发现怎么都访问出现不了这个令人舒心的界面&#xff08;ok第一个坑到…

ER图( 实体联系图)

E-R图也称实体-联系图(Entity Relationship Diagram)&#xff0c;提供了表示实体类型、属性和联系的方法&#xff0c;用来描述现实世界的概念模型。 它是描述现实世界概念结构模型的有效方法。是表示概念模型的一种方式&#xff0c;用矩形表示实体型&#xff0c;矩形框内写明…

网络爬虫--9.正则表达式

文章目录一. 正则表达式1.为什么要学正则表达式2.什么是正则表达式3.正则表达式匹配规则二. Python 的 re 模块1.re 模块的一般使用步骤2.compile 函数3.match 方法4.search 方法5.findall 方法6.finditer 方法7.split 方法8.sub 方法9.匹配中文10.贪婪模式与非贪婪模式1&#…

笔记本电池的正确使用方法

一、新买笔记本不需要激活&#xff0c;也不需要前三次的充电12小时深充深放&#xff0c;这主要是锂电池的原理和特性决定的。电池设计有电量保护&#xff0c;不可能将电量完全用完&#xff0c;当然也不可能过度充电。 二、笔记本电池的寿命受周围环境的影响很大&#xff0c;最好…

JQuery Datatables Dom 和 Language 参数详细说明

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Dom说明 定义表格控件在页面的显示顺序。 每个控件元素在数据表都有一个关联的单个字母。 l - 每页显示行数的控件f - 检索条件的控件…

Mac下的Jenkins安装

安装方式 1&#xff09;通过命令行安装 brew install jenkins&#xff0c;可能会遇到先更新 brew 的情况 https://brew.sh/index_zh-cn&#xff1b; 2&#xff09;通过 pkg 安装&#xff0c;官方网址&#xff1a;https://jenkins.io/ 安装完成后&#xff0c;会自动打开浏览器…

拼凑代码与编程

拼凑代码与编程&#xff08;Hacking Vs. Programming&#xff09;之间有什么不同&#xff1f;我听说过的一个观点是骇客可以在短时间内编许多代码&#xff0c;但是一旦发生变更&#xff0c;这些代码就要完全重写。而程序员也许会花更多的时间来编码&#xff0c;但发生变化的时候…

chrome 开启 JSONview 方法,让json数据格式化显示

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在浏览器上作接口测试的时候看到json 格式的数据是密密麻麻的一片&#xff0c;眼睛都花了.. 如&#xff1a; 设置下chrome 浏览器就好了…

百度贴吧10亿量级LAMP架构分享

导读&#xff1a;天下武功&#xff0c;唯快不破。对日益激烈的互联网竞争你所拥有的利器就是快&#xff01;本文来自百度贴吧的LAMP解决方案介绍&#xff0c;摘录至此旨在研究分享&#xff0c;看看其是如何全面支持快速迭代的。 文章内容如下&#xff1a; 贴吧是功能性产品&a…

python基础-PyYaml操作yaml文件

yaml语法 格式 它的基本语法规则如下 大小写敏感 使用缩进表示层级关系 缩进时不允许使用Tab键&#xff0c;只允许使用空格。 缩进的空格数目不重要&#xff0c;只要相同层级的元素左侧对齐即可 YAML 支持的数据结构有三种 1、对象&#xff1a;键值对的集合&#xff0c;又称为映…

N1CTF 塞题vote分析

N1CTF 塞题vote分析&#xff1a;这个题是一个uaf的漏洞题&#xff0c;我们先看看漏洞&#xff08;如下图&#xff09;&#xff0c;这两部分是很明显的对比的啊。当单独的一个count数组的数据和堆里的数据相同时候&#xff0c;就会释放堆&#xff0c;堆释放后的count还会有指针指…

网络爬虫--11.XPath和lxml

文章目录一. XML1. XML 和 HTML 的区别2. XML文档示例3. HTML DOM 模型示例4. XML的节点关系二. 什么是XPath&#xff1f;1. 选取节点2. 谓语&#xff08;Predicates&#xff09;3. 选取未知节点4. 选取若干路径5. XPath的运算符三. lxml库1. 初步使用2. 文件读取四. XPath实例…

软件测试不是一个功能

今天在工作中我对一个同事说&#xff0c;PyDev 2.5.0现在对TDD&#xff08;测试驱动开发&#xff09;提供了很酷的支持了。我并不是一个对TDD很痴迷的倡导者&#xff0c;对其它事物也一样&#xff0c;但仍不免激起了一场讨论。这个家伙&#xff0c;让我们暂叫他约翰&#xff0c…

Linux 操作系统基础知识

1.操作系统总体介绍 •CPU&#xff1a; 就像人的大脑&#xff0c;主要负责相关事情的判断以及实际处理的机制。查询指令&#xff1a; cat /proc/cpuinfo•内存&#xff1a; 大脑中的记忆区块&#xff0c;将皮肤、眼睛等所收集到的信息记录起来的地方&#xff0c;以供CPU进行判断…

Transaction 那点事儿,Spring事务管理

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Transaction 也就是所谓的事务了&#xff0c;通俗理解就是一件事情。从小&#xff0c;父母就教育我们&#xff0c;做事情要有始有终&…

8.类定义、属性、初始化和析构

类定义 类 是一个独立存放变量(属性/方法)的空间 封装&#xff1a; 类可以把各种对象组织在一起&#xff0c;作为类的属性&#xff0c;通过 . (点)运算符来调用类中封装好的对象 属性&#xff1a; 变量在类中称为属性&#xff0c;但是类中的属性不仅仅只包含变量&#x…

网络爬虫--13.数据提取之JSON与JsonPATH

文章目录一. 前言二. JSON三. json.loads()四. json.dumps()五. json.dump()六. json.load()七. JsonPath八. JsonPath与XPath语法对比九. 案例分析一. 前言 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;它使得人们很容易的进行阅读和编写。同时…