定时器、线程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).进程是表示资源分配的基本单位,又 ...
随机推荐
- safair 的css hack
在css里面使用[;attribute:value;] css参考如下: .header-share li{float: right; margin-left: 20px; [;width: 50px ...
- codeforces B. Sereja and Mirroring 解题报告
题目链接:http://codeforces.com/contest/426/problem/B 题目意思:给出一个n * m的矩阵a,需要找出一个最小的矩阵b,它能通过several次的mirror ...
- 老毛桃U盘启动盘,通过ghost创建xp系统蓝屏问题
新买的东芝笔记本只预安装了dos,找来一个老毛桃U盘启动盘,进入winpe用ghost恢复成xp系统:重启后,系统蓝屏,提示的主要报错代码 0x0000007B 与 要求“chkdsk /f”处理. ...
- 黑客技术 —— Linux 命令行
很多和正则表达式 re 是一致的: 1. 修改上次执行的命令 删除多余部分: % grep fooo /var/log/auth.log % ^o % grep foo /var/log/auth.l ...
- [Selenium] Android 中旋转屏幕,触摸,滚动
package com.learingselenium.android; import junit.framework.TestCase import org.openqa.selenium.Rota ...
- c++11实现DLL帮助类
用过DLL的人都会发现,在C++中调用dll中的函数有点繁琐,调用过程如下:在加载dll后还要定义一个对应的函数指针类型,接着调用GetProcAddress获取函数地址,再转成函数指针,最后调用函数 ...
- 【前端】CentOS 7 系列教程之四: 配置 git 服务器自动部署
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_4.html 安装pm2守护进程,备用 npm install -g pm2 创建/srv/www文件夹 ...
- bzoj2839
容斥原理+组合数学 看见这种恰有k个的题一般都是容斥原理,因为恰有的限制比较强,一般需要复杂度较高的方法枚举,而容斥就是转化为至少有k个,然后通过容斥原理解决 我们先选出k个元素作为交集,有C(n,k ...
- 【旧文章搬运】《从PEB获取内存中模块列表》的补充
原文发表于百度空间,2008-7-26========================================================================== 继续研究PE ...
- File System Programming---(三)
Accessing Files and Directories Before you can open a file, you first have to locate it in the file ...