python并发处理机制_Python并发处理
1.创建并销毁线程#!/usr/bin/python
#code to execute in an independent thread
import time
def countdown(n):
while n > 0:
print('T-minus',n)
n -= 1
time.sleep(5)
#create and launch a thread
from threading import Thread
t = Thread(target=countdown,args=(10,))
t.start()
# python concurency.py
('T-minus', 10)
('T-minus', 9)
('T-minus', 8)
('T-minus', 7)
('T-minus', 6)
('T-minus', 5)
('T-minus', 4)
('T-minus', 3)
('T-minus', 2)
('T-minus', 1)
创建一个线程实例后,需要调用start()让其运行。线程是以系统级别线程的方式执行,由操作系统管理。一旦执行,各个线程独立运行,直到目标函数返回结果,可以使用is_alive()查询一个线程实例是否正在运行。if t.is_alive():
print('The thread is still running')
else:
print('Completed')
可以使用join()来请求结合一个线程
执行上述代码时,python解释器会等待所有线程结束。对于需要时间较长的线程或者后台任务,可以考虑将线程以daemon的方式运行
t.setDaemon(True)
不能结合以daemon方式运行的线程,当主线程终止时它们会自动销毁
如果想要能够终止线程,这些线程必须能够可编程在选择的点上能够退出import time
from threading import Thread
class CountdownTask:
def __init__(self):
self._running=True
def terminate(self):
self._running=False
def run(self,n):
while self._running and n > 0:
print('T-minus',n)
n-=1
time.sleep(5)
c=CountdownTask()
t=Thread(target=c.run,args=(10,))
t.start()
c.terminate()
t.join()
由于Global Interpreter Lock(GIL)全局解释器锁的原因,Python线程被限制在任何给定时间内只能有一个线程可以执行。基于这个原因,Python线程不能用于那些需要大量计算的任务。Python线程更适合用于I/O处理,处理那些执行阻塞操作例如等待I/O,等待数据库操作结果等的代码的并发执行。
2.判断一个线程是否已经启动
Problem:
已经启动一个线程,但是想要知道它什么时候开始运行的
Solution:
Python线程的一个关键特性就是它们独立执行并且非确定性。如果程序的其他线程需要知道是否一个线程执行进一步操作之前已经达到某一个阶段。threading模块的Event对象可以帮助解决这个问题‘#!/usr/bin/python
from threading import Thread,Event
import time
#code to execute in an independent thread
def countdown(n,started_evt):
print('countdown starting')
started_evt.set()
while n > 0:
print('T-minus',n)
n -= 1
time.sleep(5)
#create the event object that will be used to signal startup
started_evt = Event()
#launch the thread and pass the startup event
print('launching countdown')
t=Thread(target=countdown,args=(10,started_evt))
t.start()
#wait for the thread to start
started_evt.wait()
print('countdown is running')
Event objects are best used for one-time events.
#!/usr/bin/python
import threading
import time
class PerodicTimer:
def __init__(self,interval):
self._interval=interval
self._flag=0
self._cv=threading.Condition()
def start(self):
t=threading.Thread(target=self.run)
t.daemon=True
t.start()
def run(self):
'''
Run the timer and notify waiting threads after each interval
'''
while True:
time.sleep(self._interval)
with self._cv:
self._flag ^= 1
self._cv.notify_all()
def wait_for_tick(self):
'''
wait for the next tick of the timer
'''
with self._cv:
last_flag=self._flag
while last_flag == self._flag:
self._cv.wait()
#example use of the timer
ptimer=PerodicTimer(5)
ptimer.start()
#two threads that synchronize on the timer
def countdown(nticks):
while nticks > 0:
ptimer.wait_for_tick()
print('T-minus',nticks)
nticks-=1
def countup(last):
n=0
while n < last:
ptimer.wait_for_tick()
print('Counting',n)
n+=1
threading.Thread(target=countdown,args=(10,)).start()
threading.Thread(target=countup,args=(5,)).start()# python event2.py
('Counting', 0)
('T-minus', 10)
('T-minus', 9)
('Counting', 1)
('Counting', 2)
('T-minus', 8)
('Counting', 3)
('T-minus', 7)
('Counting', 4('T-minus', 6)
)
('T-minus', 5)
('T-minus', 4)
('T-minus', 3)
('T-minus', 2)
('T-minus', 1)
Event对象的一个很重要的特性就是它们会唤醒所有正在等待的线程。如果想要编写一个程序只唤醒单个正在等待的线程,更好使用Semaphore或者Condition对象#!/usr/bin/python
import threading
#worker thread
def worker(n,sema):
#wait to be signaled
sema.acquire()
#do some work
print('working',n)
#create some threads
sema=threading.Semaphore(0)
nworkers=10
for n in range(nworkers):
t=threading.Thread(target=worker,args=(n,sema,))
t.start()
如果运行这个程序,一组线程会被启动,但是没有任何事情发生。应为它们都被阻塞等待获取信号量。每次释放信号量,只有一个worker将被唤醒和运行
直接在python终端执行将无任何反应并且无法终止程序# python semaphore.py
^C^C^C^C^C^C^C
在ipython终端中输入以上程序然后执行In [8]: sema.release()
In [9]: ('working', 0)
In [9]: sema.release()
In [10]: ('working', 1)
In [10]: sema.release()
('working', 2)
In [11]: sema.release()
('working'
, 3)
In [12]: sema.release()
('working', 4)
In [13]: sema.release()
('working', 5)
In [14]: sema.release()
('working', 6)
In [15]: sema.release()
In [16]: ('working', 7)
In [16]: sema.release()
In [17]: ('working', 8)
In [17]: sema.release()
('working',
9)
In [18]: sema.release()
In [19]: sema.release()
3.线程间通信
Problem:
执行程序时开启了多个线程,现在需要在这些线程之间通信或者交换数据
Solution:
也许从一个线程发送数据到另一个线程的最安全的方式就是使用 Queue模块.可以创建一个 Queue实例用于所有的线程共享。这些线程然后使用put()或者get()操作来向队列中添加或者删除项目#!/usr/bin/python
from threading import Thread
from Queue import Queue
#a thread that produces data
def producer(out_q):
while True:
#produce some data
data="producer data"
out_q.put(data)
#a thread that comsumes data
def consumer(in_q):
while True:
#get some data
data=in_q.get()
#process the data
print data
print "consumer"
#create the shared queue and launch both threads
q=Queue()
t1=Thread(target=consumer,args=(q,))
t2=Thread(target=producer,args=(q,))
t1.start()
t2.start()
执行结果:producer data
consumer
producer data
consumer
producer data
consumer
producer data
consumer
producer data
consumer
producer data
consumer
producer data
consumer
producer data
consumer
.......
.......
以上代码会不断地循环执行。当使用队列时,协调关闭producer和comsumer会比较诡异。
参考文章:
python并发处理机制_Python并发处理相关推荐
- python并发处理机制_Python并发编程—同步互斥
同步互斥 线程间通信方法 1.通信方法:线程间使用全局变量进行通信 2.共享资源争夺 共享资源:多个进程或者线程都可以操作的资源称为共享资源.对共享资源的操作代码段称为临界区. 影响 : 对共享资源的 ...
- python锁机制_python GLI锁机制
什么是GLI? Python中的线程是操作系统的原生线程,Python虚拟机使用一个全局解释器锁(Global Interpreter Lock)来互斥线程对Python虚拟机的使用.为了支持多线程机 ...
- python 消息机制_Python并发编程之线程消息通信机制任务协调(四)
. 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程无非就是创建一下,然后再start()下,实在是太简单了. 可是要知道,在真实的项目中,实际场景可要我们举 ...
- python锁机制_Python并发编程之谈谈线程中的“锁机制”(三)
大家好,并发编程 进入第三篇. 今天我们来讲讲,线程里的锁机制. 本文目录 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL( ...
- python反射机制_Python反射机制
python反射 什么是反射? 这是摘自维基百科的解释 在计算机学中,反射(英语:reflection)是指计算机程序在运行时(runtime)可以访问.检测和修改它本身状态或行为的一种能力.[1]用 ...
- python锁机制_python基础(锁机制,守护线程,线程队列,线程池)
一. 互斥锁(Lock)与递归锁(RLock)机制 1.1 由互斥锁(Lock)产生的死锁现象: #互斥锁(死锁现象): #死锁现象: from threading importLock lock=L ...
- 实践重于理论——创建一个监控程序探测WCF的并发处理机制
由于WCF的并发是针对某个封装了服务实例的InstanceContext而言的(参考<并发的本质><并发中的同步>),所以在不同的实例上下文模式下,会表现出不同的并发行为.接下 ...
- python 垃圾回收器_Python 垃圾回收机制详细
引用计数 Python语言默认采用的垃圾收集机制是『引用计数法 Reference Counting』,该算法最早George E. Collins在1960的时候首次提出,50年后的今天,该算法依然 ...
- 关于python的垃圾回收机制_Python的垃圾回收机制
知识点的铺垫 对象和引用 python作为一门动态语言,一个简单的赋值语句也是很值得研究的,重要特点就是引用对象分离. a = 1 其中整数1是一个对象,而a是一个引用.利用赋值语句,引用a指向对象1 ...
最新文章
- python美化输出模块_Python 格式化输出 ( 颜色 )
- odps结合mysql统计
- Java对象垃圾回收调用,JVM垃圾回收之哪些对象可以被回收
- 数据治理资深大咖分享:一文详解数据标准管理
- 数据结构之查找算法:折半查找
- 大佬 | 从啥也不会,到Java大佬,他就因为会了这一门绝技
- BAT程序员总结的力扣刷题指南,已经在Github了!!刷题顺序,优质题解一网打尽!
- 集成电路经典资料分享
- 数字图像处理(16): 图像颜色空间转换 和 OpenCV图像灰度化处理
- [转载] 晓说——第13期:欧洲杯硝烟再起 “阴谋论”说赌球黑幕
- PHP数组关于数字键名的问题
- GDR-Net: Geometry-Guided Direct Regression Network for Monocular 6D Object Pose Estimati
- VC中_T()的作用
- 计算机网络中的七层模型
- 沃利斯圆周率用c语言,沃利斯圆周率计算公式!
- JAVA连接FTP报530,FTP 登陆提示 530 Please login with USER and PASS
- 实习:slam算法的学习整理
- The variable XXX is being used without being initialized?
- php购物车数据表,PHP开发简单购物车功能创建数据库表
- JAVA 项目经理的职责概述
热门文章
- Spring自学日志02(对象的创建,依赖注入)
- php sql语句计算距离,sql计算经纬度得出最近距离的公式
- java fly bird小游戏_java swing实现的小游戏flybird源码附带视频配置修改教程
- dev调试时无法进入下一步_【问题解决方案】Dev C++ 无法调试的问题与解决
- http下载异常_百度网站抓取异常的原因有哪些?有什么影响和解决方法?
- 常用计算机键,计算机快捷键40个_计算机常用快捷键大全分享
- 从零开始学架构三 高性能
- Python3爬取影片入库
- C# 中 NPOI 库读写 Excel 文件的方法【摘】
- tomcat安装成功页面翻译