一、线程的其他方法
1.threading.current_thread()获取对象可以使用的方法
def fn():
pass
t = Thread(target=fn,)
t.start()
obj = threading.current_thread()
print(obj.getName(), obj.name)
print(obj.ident)
2.threading直接可以使用的方法
print(threading.enumerate())#获取当前活跃的线程的列表 print(threading.active_count())#获取当前活跃的线程的总数
二、线程队列
import queue
q = queue.Queue(5)#不给数量,这个队列就是无限大的
q.put(1)
q.put(2)
q.put(3)
q.put(4)
q.put(5)
#print(q.full())#判断队列是否已满,不过有时不太准确
#print(q.qsize())#获取队列中元素的的数量,其实这个方法里面里面也是使用的len()函数
try:
# q.put(6)#如果队列装满了,会一直停留在这里
q.put_nowait(6)#如果队列满了,会报错,使用try后,可以抓取异常,然后继续向下执行
except Exception:
print(‘zhe queue is full‘)
#print(q.empty())#查看队列是否已空,不过有时不太准确
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
try:
print(q.get())
except Exception:
print(‘zhe queue is empty‘)
2.LifoQueue--先进后出队列,获取顺序类似栈
这就是一个继承了Queue的列表,其他的方法就是继承于Queue。
q = queue.LifoQueue(3) q.put(1)#添加数据就是向列表里append()数据 q.put(2) q.put(3) print(q.get())#就是使用pop()删除列表 print(q.get()) print(q.get()) 结果: 3 2 1
第一步初始化一个列表:
def _init(self, maxsize):
self.queue = []
第二步添加数据:
def _put(self, item):
self.queue.append(item)
第三部删除数据:
def _get(self):
return self.queue.pop()
3.PriorityQueue--优先级队列
q = queue.PriorityQueue() q.put((3,‘4‘)) q.put((2,3)) q.put((1,‘d‘)) q.put((5,‘s‘)) q.put((4,‘w‘)) print(q.get()) print(q.get()) print(q.get()) print(q.get()) print(q.get()) 结果: (1, ‘d‘) (2, 3) (3, ‘4‘) (4, ‘w‘) (5, ‘s‘)
结果按照元组中第一个元素的ASCII码的升序排序后输出,如果第一元素相等,就按照第二个元素的ASCII码的升序排列,以此类推。但是,字典元素不可比较。相对应比较的两个元素必须是同类型的。
优先级队列也是一个列表:
def _init(self, maxsize):
self.queue = []
就是增加和获取时,与列表有些区别。
三、线程池
(1) map
def f(n):
time.sleep(0.5)
print(n)
t = ThreadPoolExecutor(4) # 默认数量是,CPU个数的5倍
t.map(f, range(10))
(2)submit()
def f(n):
time.sleep(0.3)
# print(n)
return n**2
Def fn(m):
Print(m)
t = ThreadPoolExecutor(4) # 默认数量是,CPU个数的5倍
t_lst = []
for i in range(10):
#功能后面的参数是无敌传参,*args,**kwargs,传递实参的个数不限制,但是形参的个数与形式也要跟实参的一一对应上
res = t.submit(f, n=i)
#t.submit()..add_done_callback(fn)#回调函数
#print(res)#返回的是结果对象
# print(res.result())#这也是一个不拿到结果,誓不罢休的方法
t_lst.append(res)
# for th in t_lst:#在shutdown()之前是每四个一次显示出来
# print(th.result())
# 相当于进程池的close()和join()两个方法,其实里面是让每个线程都调用了join().
t.shutdown()
for th in t_lst:#会一下子展示出来数据
print(th.result())
2.ProcessPoolExecutor
与ThreadPoolExcutor的使用方法一样大的。
四、协程
协程是线程里最小的执行单元。首先得下载两个模块--greenlet和gevent。
from greenleet import greenlet
def f1():
print(‘f1---1111‘)
g2.switch()
print(‘f1---2222‘)
def f2():
print(‘f2---1111‘)
g1.switch()
g1 = greenlet(f1)
g2 = greenlet(f2)
g1.switch()
结果:
f1---1111
f2---1111
f1---2222
def f1(c):
print(‘f1---1111‘,c)
g2.switch(‘Tom‘)
print(‘f1---2222‘,c)
def f2(c):
print(‘f2---1111‘,c)
g1.switch()#此处也可以添加参数,结果和现在就不一样了,可以试试看
g1 = greenlet(f1)
g2 = greenlet(f2)
g1.switch(‘TOM‘)
结果:
f1---1111 TOM
f2---1111 Tom
f1---2222 TOM
greenlet利用switch切换,执行不同代码块的功能。
2.gevent
def f1():
print(‘f1---11111‘)
gevent.sleep(1)
#time.sleep(1)
print(‘f1---22222‘)
def f2():
print(‘f2---11111‘)
gevent.sleep(2)
#time.sleep(1)
print(‘f2---2222‘)
g1 = gevent.spawn(f1)
g2 = gevent.spawn(f2)
g1.join()#需要有
g2.join()
#gevent.joinall([g1,g2])#相当于上面的两个一起
gevent只识别自己的sleep(),time.sleep()不能被识别。为了类似time.sleep()这样的阻塞被识别(还有input(),打开文件,读取数据等),使用下面的方式:
from gevent import monkey; monkey.patch_all()
Python查看API:https://docs.python.org/3.7/library/os.html
原文:https://www.cnblogs.com/asia-yang/p/10356214.html