定时器、线程queue、进程池和线程池
1.定时器
指定n秒后,执行任务
from threading import Timer,current_thread
import os def hello():
print("%s hello, world"%os.getpid())
print("%s hello, world"%current_thread().name) t = Timer(3, hello)
t.start() # after 1 seconds, "hello, world" will be printed
print(os.getpid())
print(current_thread()) #
# <_MainThread(MainThread, started 12008)>
# 12376 hello, world
# Thread-1 hello, world
定时器
2.线程queue
2.1 先进先出
import queue q=queue.Queue()
q.put('first')
q.put('second')
q.put('third') print(q.get())
print(q.get())
print(q.get())
'''
结果(先进先出):
first
second
third
'''
先进先出
2.2 后进先出
import queue q=queue.LifoQueue()
q.put('first')
q.put('second')
q.put('third') print(q.get())
print(q.get())
print(q.get())
'''
结果(后进先出):
third
second
first
'''
后进先出
2.3 优先级队列(开了会员就要先出来)
存储数据时可以设置优先级队列。数字越小(可以为负数),优先级越高,取出来的是一个元组形式。
里面put什么值就取出来什么值,只是优先级的问题。
import queue q=queue.PriorityQueue()
#put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
q.put((20,'a'))
q.put((10,'b'))
q.put((30,'c')) print(q.get())
print(q.get())
print(q.get())
'''
结果(数字越小优先级越高,优先级高的优先出队):
(10, 'b')
(20, 'a')
(30, 'c')
'''
优先级队列
3.进程池和线程池
'''
1、什么时候用池:
池的功能是限制启动的进程数或线程数,
什么时候应该限制???
当并发的任务数远远超过了计算机的承受能力时,即无法一次性开启过多的进程数或线程数时
就应该用池的概念将开启的进程数或线程数限制在计算机可承受的范围内 2、同步vs异步
同步、异步指的是提交任务的两种方式 同步:提交完任务后就在原地等待,直到任务运行完毕后拿到任务的返回值,再继续运行下一行代码
异步:提交完任务(绑定一个回调函数)后根本就不在原地等待,直接运行下一行代码,等到任务有
返回值后会自动触发回调函数 '''
concurrent.futures 高度封装的异步调用接口
ProcessPoolExecutor 进程池 提供异步调用
ThreadPoolExecutor 线程池 提供异步调用
from socket import * sever = socket(AF_INET,SOCK_STREAM)
sever.bind(("127.0.0.1",8080))
sever.listen(5)
# 无法实现并发,建立一个连接,进入通信循环,直到通信循环结束
while True:
conn,addr = sever.accept()
while True:
try:
data = conn.recv(1024)
if len(data) == 0:break
conn.send(data.upper())
except ConnectionResetError:
break
sever.close() from socket import * sever = socket(AF_INET,SOCK_STREAM)
sever.bind(("127.0.0.1",8080))
sever.listen(5)
def task(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
except ConnectionResetError:
break
sever.close()
# 还是实现不了并发,只能实现串行
while True:
conn,addr = sever.accept()
task(conn) from socket import *
from threading import Thread sever = socket(AF_INET,SOCK_STREAM)
sever.bind(("127.0.0.1",8080))
sever.listen(5)
def task(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
except ConnectionResetError:
break
sever.close() # 启动一个子线程干通信的活
# 每建立一个连接就开启一个子线程,交给子线程干通信的活,可以实现并发
while True:
conn,addr = sever.accept() t = Thread(target=task,args=(conn,))
t.start() from socket import *
from threading import Thread def task(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
except ConnectionResetError:
break
sever.close() # 将while循环放到函数下面,可以往里面传入ip,port和半连接池的最大限制数
# 这样做是已经实现并发了,但是如果有很多的客户请求,需要不停的建立线程数,电脑肯定是有上限的。
# python中的线程是操作系统的原生线程,需要操作系统来调度,同时开启太多线程,操作系统调度不过来。
# 限制线程数不是为了提高效率,是高并发情况下不得已而为之
def sever_func(ip,port,backlog = 5):
while True:
sever = socket(AF_INET,SOCK_STREAM)
sever.bind((ip, port))
sever.listen(backlog)
print("start-------")
conn,addr = sever.accept() t = Thread(target=task,args=(conn,))
t.start() if __name__ == '__main__':
sever_func("127.0.0.1",8080)
串行到并发改进
同步
同步:提交完任务后就在原地等待,直到任务运行完毕后拿到任务的返回值,再继续运行下一行代码
同步调用并不是真正意义上的串行,只是他的取值方式让程序变成了串行的工作方式。
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time
import os def task(n):
print("%s is running"%os.getpid())
time.sleep(5)
return n**2 # 默认是cpu的个数
# 如果直接在提交任务后拿到返回值就变成同步了
if __name__ == '__main__':
pool = ProcessPoolExecutor(4)
l = []
for i in range(1,10):
future = pool.submit(task,i)
l.append(future)
# print(future)
# print(future.result())
pool.shutdown(wait=True)
for m in l:
print(m.result())
同步调用
异步
异步:提交完任务(绑定一个回调函数)后根本就不在原地等待,直接运行下一行代码,等到任务有
返回值后会自动触发回调函数
回调函数:parse会在futrue有返回值时立刻触发,并且将future当作参数传给parse
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import current_thread
import os
import time
import random def task(n):
print('%s run...' %current_thread().name)
time.sleep(5)
return n**2 def parse(future):
time.sleep(1)
res=future.result()
print('%s 处理了 %s' %(current_thread().name,res)) if __name__ == '__main__':
pool=ThreadPoolExecutor(4)
start=time.time()
for i in range(1,5):
future=pool.submit(task,i)
future.add_done_callback(parse) # parse会在futrue有返回值时立刻触发,并且将future当作参数传给parse
pool.shutdown(wait=True)
stop=time.time()
print('主',current_thread().name,(stop - start))
异步调用+回掉函数
定时器、线程queue、进程池和线程池的更多相关文章
- 12 并发编程-(线程)-线程queue&进程池与线程池
queue 英 /kjuː/ 美 /kju/ 队列 1.class queue.Queue(maxsize=0) #队列:先进先出 import queue q=queue.Queue() q.put ...
- 进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型
一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: import param ...
- Python 开启线程的2中方式,线程VS进程(守护线程、互斥锁)
知识点一: 进程:资源单位 线程:才是CPU的执行单位 进程的运行: 开一个进程就意味着开一个内存空间,存数据用,产生的数据往里面丢 线程的运行: 代码的运行过程就相当于运行了一个线程 辅助理解:一座 ...
- GIL全局解释器锁+GIL全局解释器锁vs互斥锁+定时器+线程queue+进程池与线程池(同步与异步)
以多线程为例写个互斥锁 from threading import Thread ,Lockimport timemutex = Lock() n = 100 def task(): global n ...
- Java之线程与进程
一.线程与进程 线程:一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.多线程是多任务的一种特别形式,但多线程使用了更小的资源开销. 进程:一个进程包括 ...
- Linux 线程与进程,以及通信
http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...
- JoinableQueue队列,线程,线程于进程的关系,使用线程,线程的特点,守护线程,线程的互斥锁,死锁问题,递归锁,信号量
1.JoinableQueue队列 JoinableQueue([maxsize]):这就像是一个Queue对象,但是队列允许项目的使用者通知生成者项目已经被成功处理.通知进程是使用共享的信号和条件变 ...
- 线程 VS 进程
线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间; (2)资源拥有: ...
- 计算机必知必会:进程process与线程thread 进程定义为一个正在运行的程序的实例
http://www.nowamagic.net/librarys/veda/detail/1741进程和线程这对概念的理解也是很难的,至今网络上可查的资料对其的理解出入都挺大,在不同的操作系统中,如 ...
- [Other]面试复习笔记:线程与进程复习
基本概念 1. 进程的基本概念 线程(thread)是进程(processes)中某个单一顺序的控制流,也被称为轻量进程(lightweight processes).进程是表示资源分配的基本单位,又 ...
随机推荐
- 设置label的字体
label.font = [UIFont fontWithName:@"Arial-BoldItalicMT" size:24]; 字体名如下: Font Family: Amer ...
- RabbitMQ使用简述
RabbitMQ基于AMQP协议. AMQP:是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现 RabbitMQ使用:Exchange(交换机)根据routing-key(路由选择键 ...
- leetcode 681. Next Closest Time
Given a time represented in the format "HH:MM", form the next closest time by reusing the ...
- 请问snmp到底是干啥的。
这个事情分两方面来说:首先是路由器这部分.路由器开启SNMP功能之后,它能够对自己的每个接口上的流量有一个统计,当然统计的不单单只有流量.然后路由器把统计到的内容按一定的格式保存起来.这个格式是大家都 ...
- html5--6-28 css盒模型4
html5--6-28 css盒模型4 实例 学习要点 了解盒模型 元素内容.内边距.边框 和 外边距 了解盒模型的概念: CSS 盒模型规定了处理元素内容.内边距.边框 和 外边距 的方式. 最内部 ...
- 一步一步学Silverlight 2系列(14):数据与通信之WCF
一步一步学Silverlight 2系列(14):数据与通信之WCF 概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框 ...
- 一步一步学Silverlight 2系列(13):数据与通信之WebRequest
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- hadoop-3.0.0-alpha4启动
全部启动或者全部停止(注意:第一次启动需要先格式,以后就不需要格式了,不能多次格式化) 1.启动 [root@master sbin]# pwd /usr/hadoop/hadoop-3.0.0-al ...
- 西交校赛 I. GZP and CS(数位dp)
I. GZP and CS GZP love to play Counter-Strike(CS). One day GZP was playing a mod of CS. The counter- ...
- 通过HttpservletRequest对象获取客户端的真实IP地址
这篇文章主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache.Squid.nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下 在JSP里 ...