关键词挖掘爱网站,万能证件p图,wordpress 目录,建设通招标网站线程
创建线程对象
from threading import Threadt Thread()
# 功能#xff1a;创建线程对象
# 参数#xff1a;target 绑定线程函数
# args 元组 给线程函数位置传参
# kwargs 字典 给线程函数键值传参启动线程
t.start() # 启动线程回收线程
t.join([timeout]) # …线程
创建线程对象
from threading import Threadt Thread()
# 功能创建线程对象
# 参数target 绑定线程函数
# args 元组 给线程函数位置传参
# kwargs 字典 给线程函数键值传参启动线程
t.start() # 启动线程回收线程
t.join([timeout]) # 回收线程示例
import threading
from time import sleep,ctimeloops[4,2]def loop(nloop,nsec):print(start loop,nloop , at:,ctime())sleep(nsec)print(loop,nloop ,done at:,ctime())def main():threads[]nloops range(len(loops))for i in nloops:# 注意传参t threading.Thread(targetloop,args(i,loops[i]))threads.append(t)for in in nloops:threads[i].start()for i in nloops:threads[i].join()if __name__ __main__:main()自定义线程类
import threading
from time import sleep,ctimeloops[4,2]class MyThread(threading.Thread):def __init__(self,func,args,name):threading.Thread.__init__(self)self.func funcself.args argsself.name namedef run(self):self.func(*self.args)def loop(nloop,nsec):print(start loop,nloop , at:,ctime())sleep(nsec)print(loop,nloop ,done at:,ctime())def main():threads[]nloops range(len(loops))for i in nloops:t MyThread(loop,(i,loops[i]),loop.__name__)threads.append(t)for in in nloops:threads[i].start()for i in nloops:threads[i].join()if __name__ __main__:main()Event 线程同步
线程之间用于交互的一个对象这个event是一个内部的标签线程可以等待这个标签的状态
如果标签(event)没有设置则线程会一直等待此时wait是阻塞模式
import threading
# 创建线程event对象
e threading.Event()# 设置e, 使wait结束阻塞
e.wait([timeout]) # 阻塞等待e被set
e.set() # 使e回到未被设置状态
e.clear() # 查看当前e是否被设置
e.is_set() import threading
import time
import random# 先定义一个灯的函数由灯的线程去调用这个函数,绿灯是允许通过红灯是不允许通过其中绿灯10s红灯也是10s,这里就要用到事件
# 如果是绿灯则设置事件的状态如果是红灯则取消事件的状态初始状态为红灯
def light(event):if event.is_set():#设置初始状态该初始状态为事件没有状态则进程一直会阻塞event.clear()count 0while True:#进入交通灯灯循环的状态if count 10:print(----red light on----)elif count 20:print(----green light on----)if not event.is_set():event.set()else:passelse:count 0if event.is_set():event.clear()count 1time.sleep(1)# 在定义一个车的函数由车的线程去调用这个函数
def car(n,event):while True:time.sleep(1)if event.is_set():print(car [%(name)s] is running %{name:n})else:print(car [%(name)s] is waiting for red light % {name: n})event.wait()if __name__ __main__:event threading.Event()light_thread threading.Thread(targetlight,args(event,))light_thread.start()for i in range(6):t threading.Thread(targetcar, args[i,event])t.start()线程锁 Lock
lock.acquire() 上锁 如果lock已经上锁再调用会阻塞 lock.release() 解锁 with lock: 上锁 … … with 代码块解锁自动解锁
from threading import Thread, Lock
a b 0
lock Lock()def value():while True:# 上锁lock.acquire()print(a%d,b%d % (a, b)) if a ! b else print(a不等于b)# 解锁lock.release()t Thread(targetvalue)
t.start()
while True:# with 开始上锁with lock:a 1b 1# with 解锁 自动解锁
t.join()
print(程序结束)协程
协程又称微线程纤程。英文名Coroutine。一句话说明什么是线程协程是一种用户态的轻量级线程。
协程的标准定义
必须在只有一个单线程里实现并发修改共享数据不需加锁用户程序里自己保存多个控制流的上下文栈一个协程遇到IO操作自动切换到其它协程
协程拥有自己的寄存器上下文和栈。协程调度切换时将寄存器上下文和栈保存到其他地方在切回来的时候恢复先前保存的寄存器上下文和栈。因此协程能保留上一次调用时的状态即所有局部状态的一个特定组合每次过程重入时就相当于进入上一次调用的状态换种说法进入上一次离开时所处逻辑流的位置。线程是CPU控制的而协程是程序自身控制的。
生成器(yield)
Python中的生成器本身就具有状态保存和恢复的功能非常适合用来实现协程。生成器协程的最大特点在于使用yield语句来挂起函数并保存函数状态。
def simple_corouctine():print(- corouctine started)x yield # yeild接收my_continue.send发送的信息print(- corouctine received:,x)# 调用协程
my_corouctine simple_corouctine()
print(my_corouctine)
# 先启动协程让协程处于暂停状态
next(my_corouctine) # 程序通过调用方法next()将生成器推进到第一个yield语句处
# 发送消息给协程回复执行打印消息
my_corouctine.send(hello world)async/await
在Python 3.5版本以后Python提供了原生的支持协程的语法async/await。它提供了更简洁的语法更好的可读性。
import asyncio async def countdown(n):while n 0 :print(fT-minux {n})await asyncio.sleep(1)# yield from asyncio.sleep(1) # 效果同上n -1loop asyncio.get_event_loop()
loop.run_until_complete(countdown(5))import asyncio async def countdown(n,msg):while n 0 :print(f{msg} - {n})await asyncio.sleep(1)# yield from asyncio.sleep(1) # 效果同上n -1
task_list [asyncio.ensure_future(countdown(5,A)),asyncio.ensure_future(countdown(2,B)),asyncio.ensure_future(countdown(3,C))
]loop asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(task_list))获取返回值
import asyncioasync def firstCorouctine(): # 定义协程await asyncio.sleep(1)return 34434# coroutine 协同程序
coroutine firstCorouctine() # 将协程赋值给coroutine
task asyncio.ensure_future(coroutine) # 封装为task
loop asyncio.get_event_loop() # 获取事件循环
loop.run_until_complete(task) # 执行return_value task.result() # 获取协程返回值
print(协程返回的值为{}.format(return_value))gevent第三方库
gevent是一个基于协程的Python网络库它提供了一种基于yield的编程模型允许程序员编写异步非阻塞代码且易于编写和测试。
安装geventpip install gevent
import geventdef func1():print(func1 begin)gevent.sleep(3)print(func1 end)def func2():print(func2 begin)gevent.sleep(2)print(func2 end)def func3(no:int):print(func3 begin)gevent.sleep(2)print(func3 end)g1 gevent.spawn(func1)
g2 gevent.spawn(func2)
g3 gevent.spawn(func3,3) # 传参gevent.joinall([g1, g2, g3])monkey.path_all
在开头导入monkey.patch_all()非常重要会自动将 python 的一些标准模块替换成 gevent 框架这个补丁其实存在着一些坑
monkey.patch_all()网上一般叫猴子补丁。如果使用了这个补丁gevent 直接修改标准库里面大部分的阻塞式系统调用包括 socket、ssl、threading 和 select 等模块而变为协作式运行。有些地方使用标准库会由于打了补丁而出现奇怪的问题比如会影响 multiprocessing 的运行和一些第三方库不兼容比如不能兼容 kazoo。若要运用到项目中必须确保其他用到的网络库明确支持Gevent。
在实际情况中协程和进程的组合非常常见两个结合可以大幅提升性能但直接使用猴子补丁会导致进程运行出现问题将 thread 置成 False可以解决该问题缺点是无法发挥 monkey.patch_all() 的全部性能。
import gevent
from gevent import monkey
monkey.patch_all(threadFalse, socketFalse, selectFalse)pool 限制并发
协程虽然是轻量级线程但并发数达到一定量级后会把系统的文件句柄数占光。所以需要通过 Pool 来限制并发数。
import gevent
from gevent.pool import Pool
from gevent import monkey
monkey.patch_all()
import time,datetimedef test(tm):time.sleep(tm)print(时间{}.format(datetime.datetime.now()))if __name__ __main__:task []# 限制最大并发pool Pool(5)# 分配100个任务最大并发数为5for i in range(100):task.append(pool.spawn(test,5))gevent.joinall(task)gevent 虽然在编程方面很方便开头使用 monkey.patch_all()就能让你的同步代码享受到异步的性能。但坑也是存在的所以复杂的业务场景不推荐使用 gevent可以使用python 标准库中的 asyncio。