Python多线程(四)

如何使用线程本地数据

实际案例:

实现了一个web视频监控服务器,服务端采集摄像头数据,客户端使用浏览器通过http请求接收数据,服务器使用推送的方式(multipart/x-mixed-replace)一直使用一个tcp连接向客户端传递数据,这种方式将持续占用一个线程,导致单线程服务器无法处理多客户端请求

改写程序,在每个吕处理一个客户端请求,支持多客户端访问

importos, cv2, time,struct, threading

fromhttp.serverimportHTTPServer,BaseHTTPRequestHandler

fromsocketserverimportTCPServer,ThreadingTCPServer

fromthreadingimportThread, RLock

fromselectimportselect

classJpegStreamer(Thread):#负责采集数据,独立线程,相当于数据源

def__init__(self,camera):

Thread.__init__(self)

self.cap =cv2.VideoCapture(camera)

self.lock = RLock()

self.pipes = {}

defregister(self):

pr, pw = os.pipe()

self.pipes[pr] = pw

returnpr

defunregister(self,pr):

os.close(pr)

os.close(pw)

defcapture(self):

cap =self.cap

whilecap.isOpened():

ret, frame = cap.read()

ifret:

#ret, data =cv2.imencode('.jpg', frame)

ret, data = cv2.imencode('.jpg', frame, (cv2.IMWRITE_JPEG_QUALITY,40))

yielddata.tostring()

defsend(self,frame):

n = struct.pack('l', len(frame))

iflen(self.pipes):

forpipeinpipes:

os.write(pipe, n)

os.write(pipe, frame)

defrun(self):

forframeinself.capture():

self.send(frame)

classJpegRetriever(object):#从streamer中获取数据

def__init__(self,streamer):

self.streamer =streamer

self.local =threading.local()

defretrieve(self):

whileTrue:

n = struct.unpack('l', ns)[]

yielddata

def__enter__(self):

ifhasattr(self.local,'pipe'):

raiseRuntimeError()

returnself.retrieve()

def__exit__(self,*args):

returnTrue

classHandler(BaseHTTPRequestHandler):#处理http请求

retriever =None

@staticmethod

defsetJpegRetriever(retriever):

Handler.retriever = retriever

defdo_GET(self):

ifself.retrieverisNone:

raiseRuntimeError('no retriver')

ifself.path !='/':

return

self.send_response(200)

self.send_header('Content-type','multipart/x-mixed-replace;boundary=abcde')

self.end_headers()

withself.retrieverasframes:

forframeinframes:

self.send_frame(frame)

defsend_frame(self,frame):

s ='--abcde\r\n'

s +='Content-Type:image/jpeg\r\n'

s +='Content-Length:%s\r\n\r\n'% len(frame)

if__name__ =='__main__':

streamer = JpegStreamer()

streamer.start()

retriever = JpegRetriever(streamer)

Handler.setJpegRetriever(retriever)

print('Startserver...')

httpd = ThreadingTCPServer(('',9000), Handler)

httpd.serve_forever()

本文来自企鹅号 - 胡博士小作坊媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏京东技术

必须掌握的ADB命令 | 让你的测试事半功倍

ADB的全称是Android Debug Bridge,是一个与模拟器或者连接设备通讯的桥梁。ADB是CS结构包含三个部分:

1.8K40
来自专栏王硕

原 Windows 64位下 PostgreSQL的编译

403110
来自专栏互联网技术栈

Redis 队列

举例: 队列主要用在系统解耦、流量削峰、异步处理、数据顺序处理等场景。新手在使用时可能会犯一些常见的错误。下面讲一个新手容易犯的错误,在这个示例中把队列的入...

55550
来自专栏Spark学习技巧

高性能:MYSQL异步客户端

实时处理领域,当需要使用外部存储数据染色的时候,需要慎重对待,不能让与外部系统之间的交互延迟对流的整个进度取决定性的影响。

48920
来自专栏happyJared

Java开发人员常用的服务配置(Nginx、Tomcat、JVM、Mysql、Redis)

45810
来自专栏salesforce零基础学习

salesforce 零基础学习(十八)WorkFlow介绍及用法

说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow。 当你分配许多任务,定期发送电子邮件,记录修改时,可...

236100
来自专栏偏前端工程师的驿站

网页优化系列一:合并文件请求(asp.net版)

  最近因公司需要对网站的优化处理学习了一番,现在借本系列博文与大家分享一下自己的学习成果,有纰漏处请大家多多指正。   首先推荐一篇十分全面的网页优化文章  ...

22480
来自专栏云计算教程系列

使用Capistrano,Nginx和Puma在Ubuntu 14.04上部署Rails应用程序

Rails是一个用Ruby编写的开源Web应用程序框架。Nginx是一种高性能HTTP服务器,反向代理和负载均衡器,以其并发性,稳定性,可伸缩性和低内存消耗而著...

17840
来自专栏漫漫全栈路

Nginx配置文件nginx.conf详解

最近折腾Ubuntu比较多,也基本原理了Windows和IIS了,论一个软狗的堕落史。既然换到Ubuntu系统上来,勉强算个web开发人员的我当然用的最多的就...

74670
来自专栏后端技术探索

7个角度进行nginx性能优化

在大多数情况下,一个常规安装的Nginx对网站来说已经能很好地工作了。然而如果想挤压出Nginx的性能,就需要了解哪些指令会影响Nginx性能,在本文中将解释N...

17320

扫码关注云+社区

领取腾讯云代金券