1.线程的其他方法

from threading import Thread,current_thread
import time
import threading
def f1(n):
time.sleep(1)
print('子线程名称',current_thread().getName())#获取线程名
if __name__=='__main__':
t1=Thread(target=f1,args=(1,))
t1.start()
print('主线程名称',current_thread().getName())
print('主进程id',current_thread().ident)
print(current_thread())#当前线程的对象
print(threading.enumerate())#当前正在运行的线程的一个列表
print(threading.active_count())#当前正在运行的线程的数量
#########结果########
主线程名称 MainThread
主进程id 7512
<_MainThread(MainThread, started 7512)>
[<_MainThread(MainThread, started 7512)>, <Thread(Thread-1, started 5680)>]
2
子线程名称 Thread-1

2.线程队列

import queue
###先进先出
q=queue.Queue(3)
q.put(1)
q.put(2)
print('当前队列内容长度',q.qsize())
q.put(3)
print('查看队列是否满了',q.full()) print(q.get())
print(q.get())
print('查看队列是否为空',q.empty())
print(q.get())#在多打一个get会形成程序阻塞
print('查看队列是否为空',q.empty())
try:
q.get_nowait()#报错queue.Empty
except Exception:
print('队列空了')
############################
当前队列内容长度 2
查看队列是否满了 True
1
2
查看队列是否为空 False
3
查看队列是否为空 True
队列空了
####先进后出 类似于栈
import queue
q = queue.LifoQueue(3)
#
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
##############
3
2
1
####优先级队列
import queue
q=queue.PriorityQueue(5)
q.put((5,'alex'))
q.put((2,'宝宝'))
q.put((4,'大力'))
print(q.get())
print(q.get())
print(q.get())
##########
(2, '宝宝')
(4, '大力')
(5, 'alex')
#如果优先级数字相同,如果数据类型不同会报错,类型相同会对比元祖中的第二行英语字母

3.线程池

map方法

import time
from concurrent.futures import ThreadPoolExecutor
from threading import current_thread def func(n):
time.sleep(1)
print(n)
# print(n,current_thread().ident) if __name__ == '__main__':
t_p = ThreadPoolExecutor(4)
map_res = t_p.map(func,range(10)) #异步执行的,map自带join功能
print(map_res)
print([i for i in map_res])
#######################
<generator object Executor.map.<locals>.result_iterator at 0x00000000029E94F8>
012 3 4
5
6
7
89
[None, None, None, None, None, None, None, None, None, None]#会取不到值
concurrent.futures 写法
import time
from threading import current_thread
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
def func(n):
time.sleep(0.1)#此处等待一秒是为了将取值时候的打印结果进行区分
# print(n)
return n
if __name__ == '__main__':
t_p = ThreadPoolExecutor(4)#可以进行线程进程切换
# t_p=ProcessPoolExecutor(4)
t_res_lst = []
for i in range(10):
res_obj =t_p.submit(func,i) #提交执行函数,返回一个结果对象,i作为任务函数的参数
t_res_lst.append(res_obj)
t_p.shutdown() #起到原来的close阻止新任务进来 + join的作用,等待所有的线程执行完毕
# print("t_res_lst",t_res_lst) #<Future at 0x1fa10a43400 state=finished returned int> 加了shutdown后全部变为finished
#<Future at 0x19d37f5c7f0 state=running>, <Future at 0x19d37f5c9b0 state=pending>不加shutdo时
for e_res in t_res_lst:
print(e_res.result())
# t_p.shutdown()
#在不加shutdown时,主线程在循环列表时,也是每一个进行取值,
# 但是由于可以有四个对象可以一起取值,(拿前四个为例,)
# 也就是当列表循环到4个时此时会等待将近1s
# 因为在执行函数有停留,但线程池可以四个同时执行,因此会有4个结果一起出来
#但是当加了shutdown时,此时线程会全部执行完毕,然后在列表里是,此时的对象已经全部执行完毕
########################
0
1
2
3
4
5
6
7
8
9

4.协程

协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,在我们自己的程序里面来控制任务的切换。
现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),

import gevent
from gevent import monkey;monkey.patch_all()#本身不认识其他模块中的IO操作,但是如果我们在导入其他模块之前执行 就能够认识
import time def f1():
print('第一次f1')
# print(threading.current_thread().getName())
# gevent.sleep(1)
time.sleep(2)
print('第二次f1')
def f2():
# print(threading.current_thread().getName())
print('第一次f2')
# gevent.sleep(2)
time.sleep(2)
print('第二次f2')
s = time.time()
g1 = gevent.spawn(f1) #异步提交了f1任务
g2 = gevent.spawn(f2) #异步提交了f2任务
# g1.join()
# g2.join()
gevent.joinall([g1,g2])
e = time.time()
print('执行时间:',e-s)
print('主程序任务')
#######################
第一次f1
第一次f2
第二次f1
第二次f2
执行时间: 2.0021142959594727
主程序任务

下面是理解 :可看 可不看

#####生成器写法
import time
def f1():
for i in range(2):
time.sleep(0.5)
print('f1>>',i)
yield
def f2():
g = f1()
for i in range(2):
time.sleep(0.5)
print('f2>>', i)
next(g)
f1()
f2()
############
f2>> 0
f1>> 0
f2>> 1
f1>> 1
#######greenlet模块
import time
from greenlet import greenlet
def f1(s):
print('第一次f1'+s)
g2.switch('taibai') #切换到g2这个对象的任务去执行
time.sleep(1)
print('第二次f1'+s)
g2.switch()
def f2(s):
print('第一次f2'+s)
g1.switch()
time.sleep(1)
print('第二次f2'+s)
g1 = greenlet(f1) #实例化一个greenlet对象,并将任务名称作为参数参进去
g2 = greenlet(f2)
g1.switch('alex') #执行g1对象里面的任务
###########
#首先会执行g1的switch(alex)也就是执行f1 print('第一次f1'+alex)
#往下就会执行f2 进行传参taibai 会打印 第一次f2taibai
#往下 执行了g1也就是f1 print('第二次f1'+s)
#往下继续走 print('第二次f2'+taibai)
##########结果
第一次f1alex
第一次f2taibai
第二次f1alex
第二次f2taibai

回调函数

#######回调函数
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
def f1(n,s):
return n+s
def f2(n):
print('回调函数>>',n.result())
if __name__ == '__main__':
tp=ThreadPoolExecutor(4)
res=tp.submit(f1,11,12).add_done_callback(f2)
#####################
回调函数>> 23

python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)的更多相关文章

  1. Python之路(第四十七篇) 协程:greenlet模块\gevent模块\asyncio模块

    一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 协程相比于线程,最大的区别在于 ...

  2. 网络编程基础--协程--greenlet切换---gevent自动识别 IO ---

    协程: 1 单线程来实现并发---协程: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 只 ...

  3. day 34 线程队列 线程池 协程 Greenlet \Gevent 模块

    1 线程的其他方法 threading.current_thread().getName()    查询当前线程对象的名字 threading.current_thread().ident      ...

  4. 协程greenlet、gevent

    greenlet为了更好使用协程来完成多任务,python中greenlet模块对其封装,从而使得切换任务变得更加简单安装方式 pip3 install greenlet 示例代码: from gre ...

  5. 进程池线程池 协程 gvent 单线程实现并发套接字

    1.基于多线程实现套接字服务端支持并发 服务端 from socket import * from threading import Thread def comunicate(conn): whil ...

  6. python 并发专题(六):协程相关函数以及实现(gevent)

    文档资源 http://sdiehl.github.io/gevent-tutorial/ 一.协程实现 线程和协程 既然我们上面也说了,协程也被称为微线程,下面对比一下协程和线程: 线程之间需要上下 ...

  7. python全栈开发 * 线程队列 线程池 协程 * 180731

    一.线程队列 队列:1.Queue 先进先出 自带锁 数据安全 from queue import Queue from multiprocessing import Queue (IPC队列)2.L ...

  8. Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程

    Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...

  9. 线程队列 concurrent 协程 greenlet gevent

    死锁问题 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...

随机推荐

  1. BZOJ5417[Noi2018]你的名字——后缀自动机+线段树合并

    题目链接: [Noi2018]你的名字 题目大意:给出一个字符串$S$及$q$次询问,每次询问一个字符串$T$有多少本质不同的子串不是$S[l,r]$的子串($S[l,r]$表示$S$串的第$l$个字 ...

  2. P1028 数的计算

    P1028 题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自然数,但该 ...

  3. Mysql partition by

    一,看原表 select * from `user`; 二,查询同组年级最大的 select username ,SUBSTRING_INDEX( GROUP_CONCAT(age order by ...

  4. F - Count the Colors ZOJ - 1610 线段树染色(染区间映射)

    题意:给一段0-8000的线段染色 问最后 颜色x 有几段 题解:标准线段树  但是没有push_up  最后查询是单点按顺序查询每一个点 考虑过使用区间来维护不同的线段有多少种各色的线段  思路是 ...

  5. 【XSY2484】mex 离散化 线段树

    题目大意 给你一个无限长的数组,初始的时候都为\(0\),有3种操作: 操作\(1\)是把给定区间\([l,r]\)设为\(1\): 操作\(2\)是把给定区间\([l,r]\)设为\(0\): 操作 ...

  6. reactNative 基础

    参考:中文网,极客 一 . 基本程序: import React, { Component } from 'react'; import { Text } from 'react-native'; e ...

  7. 【正睿oi省选十连测】第一场

    四小时写了两个暴力??自闭 [原来这就是神仙们的分量Orz rank 56/75 可以说是无比垃圾了 下周目标:进步十名?[大雾 T1 题意:有n个点的图 点有点权Ai 也有点权Bi = A_1 + ...

  8. JXOI 2017 简要题解

    「JXOI2017」数列 题意 九条可怜手上有一个长度为 \(n\) 的整数数列 \(r_i\) ,她现在想要构造一个长度为 \(n\) 的,满足如下条件的整数数列 \(A\) : \(1\leq A ...

  9. 【CF487E】Tourists(圆方树)

    [CF487E]Tourists(圆方树) 题面 UOJ 题解 首先我们不考虑修改,再来想想这道题目. 我们既然要求的是最小值,那么,在经过一个点双的时候,走的一定是具有较小权值的那一侧. 所以说,我 ...

  10. mysql安转过程中出现的问题! Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exis

    net start mysql启动失败,报错信息如上,因缺少mysql这个库 所以跳过 在my.ini中添加 --skip-grant-tables 再启动mysql 然后进入mysql 倒入一个从其 ...