线程,有时被称为轻量级进程,是程序执行流的最小单元
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指进行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
python中多个cpu无法同时处理一个进程或其子进程,多个cpu可以同时处理多个线程
1 import time
def f1(arg):
time.sleep(1)
print(arg)
import threading
t = threading.Thread(target = f1,args = (123,))
#t.setDaemon(True)#表示主线程不等子线程
t.start()#不代表当前线程会立即被执行
t.join(2) #表示主线程到此等待。。。直到子线程执行完成#参数,表示住线程再次最多等待n秒 print('end')
#一秒后显示
>>>123
>>>end import time
def f1(arg):
time.sleep(1)
print(arg)
import threading
t = threading.Thread(target = f1,args = (123,))
t.setDaemon(True)#表示主线程不等子线程
t.start()#不代表当前线程会立即被执行
#t.join(2) #表示主线程到此等待。。。直到子线程执行完成#参数,表示住线程再次最多等待n秒 print('end')
#立即显示
>>>end
#我们可以写个类继承threading模块的Thead类并加入自定义的构造方法,
#用来添加新功能
class MyThread(threading.Thread):
def __init__(self,func,args):
self.func =func
self.args = args
#继承父类的构造方法
super(MyThread,self).__init__() def run(self):
self.func(self.args) def f2(arg):
print(arg) obj = MyThread(f2,123)
obj.start()
>>>123

队列

 #Python中,队列是线程间最常用的交换数据的形式。Queue模块是提供队列操作的模块,不同的队列应用在不同的场景中
#queue.Queue先进先出队列
#queue.LifoQueue,后进先出队列
#queue.PriorityQueue,优先级队列
#queue.deque,双向队列 import queue
q = queue.Queue(3)#参数为队列中最大个数
print(q.empty())#判断是否为空
>>>True
print(q.full())#判断队列是否已满
>>>False
q.put(11)
>>>传入元素
q.put(22)
>>>传入元素
#q.put(33,block=False)#最大值为2传入第三个的时候默认阻塞
print(q.qsize())#真实队列剩余个数
>>>2
print(q.maxsize)#最大个数
>>>3
print(q.get())#取值当队列中取完之后继续取得时候阻塞
>>>11
q.task_done()#任务完成
print(q.get())#取值
>>>22
q.task_done()#任务完成,用于释放队列
q.join()#不带这个的时候程序完成后释放队列,加上的时候阻塞
 #先进后出队列
q = queue.LifoQueue()
q.put(123)
q.put(456)
print(q.get())
#>>>456 #优先级队列
q = queue.PriorityQueue()
q.put((1,'alex1'))
q.put((1,'alex2'))
q.put((3,'alex3'))
print(q.get())
>>>(1, 'alex1') #双向队列
q= queue.deque()
q.append(123)
q.append(333)
q.appendleft(456)
#从左侧插入队列
print(q.pop())#从右侧取值
print(q.popleft())#从左侧取值
>>>333
>>>456

生产者消费者模型

#生产者消费者模型
import queue
import threading
import time #创建队列
q = queue.Queue(50) #定义消费者
def productor(arg):
'''
买票
:param arg:
:return:
'''
while True:
q.put(str(arg) + '号产生订单')#提交到队列 #创建300个线程发送请求
for i in range(300):#300个线程同时提交订单相当于300个人同时提交订单
t = threading.Thread(target= productor,args= (i,))
t.start() #定义生产者
def consumer(arg):
'''
服务器后台
:param arg:
:return:
'''
while True:
print(str(arg) + '处理了'+q.get())#进程从队列中取订单进行处理 #3个线程同时工作
for j in range(3):
t = threading.Thread(target=consumer,args=(j,))
t.start()

线程锁

 #线程锁
import threading
import time NUM = 10
#线程锁线程执行进程通过的接口,用来限制多个线程同时修改一个数据
def func(l):
global NUM
#上锁
l.acquire()
NUM -=1
time.sleep(2)
print(NUM)
#开锁
l.release()
#单层锁
lock = threading.Lock()
#多层锁
#lock = threading.RLock() for i in range(30):
t = threading.Thread(target=func,args = (lock,))
t.start()

信号量

 #设置可通过线程个数
import threading
import time
NUM =10
def func(i,l):
global NUM
#上锁
l.acquire()
NUM -=1
time.sleep(2)
print(NUM,i)
#开锁
l.release() #调用信号量设置每次多少个线程处理进程
lock = threading.BoundedSemaphore(5) for i in range(30):
t = threading.Thread(target= func,args=(i,lock,))
t.start()
 #event相当于红绿灯,通过一个标识来批量管理线程
import threading def func(i,e):
print(i)
e.wait()#检测时什么灯,如果是红灯,停,绿灯,行
print(i+100) event = threading.Event() for i in range(10):
t = threading.Thread(target= func,args = (i,event,))
t.start() event.clear()#设置成红灯
inp = input('>>>')
if inp == '':
event.set()#设置成绿灯
 #根据条件限定线程的执行
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#设置条件设置线程数第一种方式
import threading
def func(i,con):
print(i)
con.acquire()
con.wait()
print(i+100)
con.release() c = threading.Condition()
for i in range(10):
t = threading.Thread(target=func,args=(i,c))
t.start() while True:
inp = input('>>>')
if inp == 'q':
break
c.acquire()
c.notify(int(inp))#根据输入设置通过几个线程数
c.release() #第二种
import threading def condition():
ret =False
r = input('>>>')
if r == 'true':
ret =True
else:
ret = False
return ret def func(i,con):
print(i)
con.acquire()
# 设置condition函数为条件返回true继续运行,条件不成立则不执行此线程
con.wait_for(condition)
print(i+100)
con.release() c = threading.Condition()
for i in range(10):
t = threading.Thread(target=func,args=(i,c))
t.start()

Timer

 #定时器
form threading import Time def hello():
print('hello')
t = Timer(1,hello)#一秒后执行
t.start()

线程池

 import queue
import threading
import time class ThreadPool:
def __init__(self,maxsize):
self.maxsize = maxsize
self._q = queue.Queue(maxsize)#创建队列
for i in range(maxsize):
self._q.put(threading.Thread)#将创建线程的类放入队列 def get_thread(self):
return self._q.get()#获取队列的值 def add_thread(self):
self._q.put(threading.Thread) pool = ThreadPool(5)#设置线程池
def task(arg,p):
print(arg)
time.sleep(1)
p.add_thread()#添加新的线程 for i in range(100):
t = pool.get_thread()#当获取5次后,阻塞在此
obj = t(target = task,args = (i,pool,))#创建线程调用函数task
obj.start()
 #第二种创建线程池方式
#!/usr/bin/env python
# -*- coding:utf-8 -*- import queue
import threading
import contextlib
import time StopEvent = object()
class Pool:
def __init__(self,max_num,max_task_num=None):
if max_task_num:
self.q=queue.Queue(max_task_num)#创建队列并指定接受任务最大数
else:
self.q = queue.Queue()#不指定参数
self.max_num = max_num#最多有多少个线程
self.cancel = False
self.terminal = False
self.generate_list = []#已创建线程
self.free_list = []#空闲线程 def run(self,func,args,callback = None):#接收参数
if self.cancel:
return
if len(self.free_list) ==0 and len(self.generate_list) < self.max_num:#当没有空闲线程并且,已创建的线程没有达到最大值
self.generate_thread() #创建新线程调generte_thread函数
w = (func,args,callback,)#将参数传入队列中
self.q.put(w)#将参数作为元组传入队列中 def generate_thread(self):
'''
创建线程
:return:
'''
t = threading.Thread(target=self.call)#执行call函数
t.start()
def call(self):
'''
让线程执行任务
:return:
'''
current_thread = threading.currentThread#获取当前线程数
self.generate_list.append(current_thread)#传入已创建线程列表中
event =self.q.get()#获取任务
while event != StopEvent:#如果任务不为空
func,args,callback = event#将传过来的参数赋值给event
try:
result = func(args)#执行action(i)
success = True#任务执行成功
except Exception as e:
success = False#action任务执行失败
if callback is not None:
try:
callback(success,result)
except Exception as c:
pass
#event.self.q.get()#继续去任务,当存在任务则执行action不存在则删除当前进程
with self.worker_state(self.free_list,current_thread):#任务执行完成后设置该线程为空闲
if self.terminal:#如果是空闲的
event = StopEvent
else:
event = self.q.get()#如果不是空闲的,则去取任务
else:
self.generate_list.remove(current_thread)#如果任务为空则删除当前线程 def close(self):
'''
执行完所有任务后,所有线程停止
:return:
'''
self.cancel = True
full_size = len(self.generate_list)#统计线程个数
while full_size:#根据线程个数传入对应个数的False标志
self.q.put(StopEvent)
full_size -=1 def terminate(self):
"""
无论是否还有任务,终止线程
"""
self.terminal = True while self.generate_list:
self.q.put(StopEvent)
self.q.empty() @contextlib.contextmanager
def worker_state(self, state_list, worker_thread):
"""
用于记录线程中正在等待的线程数
"""
state_list.append(worker_thread)
try:
yield
finally:
state_list.remove(worker_thread)
pool = Pool(5) def action():
pass
def callback(i):
print(i)
for i in range(300):
ret = pool.run(action,(i,),callback)#将函数i的值与callback函数传入类中

python-线程进程与队列的更多相关文章

  1. python 线程 进程

    1.进程与线程优.缺点的比较总言:使用进程和线程的目的,提高执行效率. 进程: 优点:能利用机器的多核性能,同时进行多个操作. 缺点:需要耗费资源,重新开辟内存空间,耗内存. 线程: 优点:共享内存( ...

  2. python 线程 进程 协程 学习

    转载自大神博客:http://www.cnblogs.com/aylin/p/5601969.html 仅供学习使用···· python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和 ...

  3. python 线程进程

      一 线程的2种调用方式 直接调用 实例1: import threading import time def sayhi(num): #定义每个线程要运行的函数 print("runni ...

  4. Python 线程&进程与协程

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  5. python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)

    1.线程的其他方法 from threading import Thread,current_thread import time import threading def f1(n): time.s ...

  6. python线程进程

    多道技术: 多道程序设计技术 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行.即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种硬.软件资源.当一道程序因I/O请 ...

  7. python线程,进程,队列和缓存

    一.线程 threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 创建线程的两种方式1.threading.Thread import threading def f1(arg): ...

  8. python 线程,进程28原则

    基于函数实现 from threading import Thread def fun(data, *args, **kwargs): """ :param data: ...

  9. python 线程/进程模块

    线程的基本使用: import threading # ###################### 1.线程的基本使用 def func(arg): print(arg) t = threading ...

  10. python 线程 进程 标识

    s = '%s%s%s%s%s%s%s%s' % ( time.strftime('%Y%m%d %H:%M:%S', time.localtime(time.time())), ' os.getpp ...

随机推荐

  1. 【洛谷5251】[LnOI2019] 第二代图灵机(线段树+ODT)

    点此看题面 大致题意: 有单点修改数字和区间着色两种修改操作,询问你某段区间内包含所有颜色且数字和最小的子区间的数字和,或某段区间内没有重复颜色且数字和最大的子区间的数字和.数据随机. \(ODT\) ...

  2. P1540 机器翻译

    题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词,软件会先 ...

  3. C++STL之vector向量容器

    vector向量容器   vector向量容器不但能向数组一样对元素进行随机访问, 还能在尾部插入元素 vector具有内存自动管理的功能, 对于元素的插入和删除, 可动态调整所占的内存空间 vect ...

  4. 获取页面的url

    设当前页完整地址是:http://www.jb51.net/aaa/bbb.aspx?id=5&name=kelli "http://"是协议名 "www.jb5 ...

  5. hadoop分类输出

    import org.apache.hadoop.io.Text; import java.io.IOException;import java.util.Iterator;import java.u ...

  6. 《JavaScript高级程序设计第三版》——细碎知识痛点整理(第六章)

    面向对象的程序设计 对象是一组没有特定顺序的值6.1.1 属性类型ECMAScript中有两种属性:数据属性和访问器属性.1. 数据属性Configurable 表示能否通过delete删除属性从而重 ...

  7. javaWeb css图文混排

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. FAT32中文版分析+补充(2)

    从Offset 36(0x24)开始FAT12/16的内容开始区别于FAT32,现在分两个表格列出来,下表为FAT12/16的内容: 名称 Offset(Byte) 大小(Byte) 描述 BS_dr ...

  9. 爬虫学习(十九)——Scrapy的学习及其使用

    Scrapy框架的介绍 Scrapy,非常的强悍,通过python语言编写的,非常知名的爬虫框架 框架工作流程 框架流程图 基本工作流程; 1.引擎向spiders要url 2.引擎将要爬取的url给 ...

  10. zabbix服务端安装配置

    1.安装好httpd,mysql,php yum install httpd php mysql mysql-devel php-xmlwriter php-gd php-mbstring php-b ...