首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程和代理增加了30秒的延迟。我能做些什么来避免

多线程和代理增加了30秒的延迟。我能做些什么来避免
EN

Stack Overflow用户
提问于 2011-02-21 23:14:43
回答 2查看 827关注 0票数 1

我使用PyQt、QThreads和couchdb-python与本地局域网上的couchDB实例通信。

为了测试在网络速度慢的情况下多线程是否会工作,我在GUI和沙发之间放置了一个代理。

联网已记录。日志以如下开头

代码语言:javascript
复制
13:52:46.303 (1) send: HEAD /cubic HTTP/1.1CRLFHost: localhost:5981CRLFContent-Length: 0CRLFAccept: application/jsonCRLFUser-Agent: CouchDB-Python/0.8CRLFCRLF

13:52:46.308 (1) recv: HTTP/1.1 200 OKCRLFServer: CouchDB/1.0.1 (Erlang OTP/R13B)CRLFDate: Mon, 21 Feb 2011 13:47:18 GMTCRLFContent-Type: application/jsonCRLFContent-Length: 219CRLFCache-Control: must-revalidateCRLFCRLF
13:53:16.312 (1) recv: link closed
13:53:16.319 (2) send: GET /cubic/_design/Company/_view/by_name HTTP/1.1CRLFHost: localhost:5981CRLFContent-Length: 0CRLFAccept: application/jsonCRLFUser-Agent: CouchDB-Python/0.8CRLFCRLF
13:53:16.330 (2) recv: HTTP/1.1 200 OKCRLFTransfer-Encoding: chunkedCRLFServer: CouchDB/1.0.1 (Erlang OTP/R13B)CRLFEtag: "243QGZGN1ETGA4VN9H1OMB86Z"CRLFDate: Mon, 21 Feb 2011 13:47:48 GMTCRLFContent-Type: application/jsonCRLFCache-Control: must-revalidateCRLFCRLF
13:53:16.331 (2) recv: a0CRLF{"total_rows":9,"offset":0,"rows":[CRLF{"id":"c182c1a2f71c3547ccee45556300770e","key":["A first Company","231","345 East of Eden" ,"Manchester",null],"value":null}CRLF
13:53:16.332 (2) recv: 77CRLF,CRLF{"id":"c182c1a2f71c3547ccee455563001254","key":["C-U-B","1","9-11 March Business Centre","March",null],"value":null}CRLF72CRLF,CRLF{"id":"421261e8a3311c356c4900185800d976","key":"Four","104","4 Fourth street","Four Score",null],"value":null}CRLF74CRLF,CRLF{"id":"c182c1a2f71c3547ccee455563003de8","key":["Fred Smith","431","30 High street","Somehow",null],"value":null}CRLF
13:53:16.334 (2) recv: 83CRLF,CRLF{"id":"7bc7f2014593d108b5b681fe03002ad6","key":["Ian Hobson","1002","31 Sheerwater Dr","Northampton, Nhants",null],"value":null}CRLF76CRLF,CRLF{"id":"c182c1a2f71c3547ccee455563003139","key":["Julie Bloggs","302","30 Back Lane","Somewhere",null],"value":null}CRLF7cCRLF,CRLF{"id":"c182c1a2f71c3547ccee455563002e87","key": "Kingfisher Group","323","33 Westmister Rd","Londonx",null],"value":null}CRLF
13:53:16.335 (2) recv: 7aCRLF,CRLF{"id":"c182c1a2f71c3547ccee455563005894","key":["New Company","212","34 Back Street","Another Town",null],"value":null}CRLF72CRLF,CRLF{"id":"421261e8a3311c356c4900185800d7e2","key":["Three","103","3 High Street","Liverpool 8",null],"value":null}CRLF4CRLFCRLF]}CRLF1CRLFLFCRLF0CRLFCRLF
13:53:46.337 (2) recv: link closed

除了在13:52:46.308打开数据库后有30秒的延迟,而recv链接超时之外,这与预期完全一样。直到发生这种情况,代码才能打开发生在13:53:16.319的视图

但是,代理正在使用不同的线程{(2)而不是(1)}。应用程序部分在没有代理的情况下工作得很好,所以我怀疑是代理。

代理代码基于微代理,如下所示

代码语言:javascript
复制
import re, sys, datetime
import socket 
import threading 
PORT = 5981
class ConnectionThread(threading.Thread): 
    def __init__(self, (conn,addr),id): 
        self.conn = conn 
        self.addr = addr
        self.id = id
        threading.Thread.__init__(self)

    def report(self,data,dir):
        txt = data.replace("\n",'LF')
        txt = txt.replace("\r",'CR')
        now = datetime.datetime.now()
        print "%s (%s) %s: %s" % (now.isoformat()[11:23],self.id,dir,txt)      

    def run(self): 
        data = self.conn.recv(1024*1024) 
        request = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        request.connect(('192.168.0.1',5984)) 
        self.report(data,'send')
        request.send(data) 
        while True: 
            temp = request.recv(1024) 
            if ('' == temp):
                self.report('link closed','recv')
                break 
            self.report(temp,'recv')
            self.conn.send(temp)
        self.conn.close()

class ProxyThread(threading.Thread): 
    def __init__(self, port): 
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        self.sock.bind(('localhost', port))
        self.count = 1
        threading.Thread.__init__(self) 
    def run(self): 
        self.sock.listen(3) 
        while True:
            temp = ConnectionThread(self.sock.accept(),self.count)
            temp.start()   # each message handled in own thread
            self.count += 1
if __name__ == "__main__": 
    print "Starting a proxy on port", PORT
    proxy = ProxyThread(PORT) 
    proxy.run() 

打开数据库的请求和视图的请求都是在同一个(非GUI)线程中发出的。为什么会出现延迟?

我怎样才能改变事情,让它不再发生呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-22 02:01:07

您的循环仅从被代理的连接的一端读取。因此,当应答从服务器转发到客户端时,当客户端断开连接时,代码不会注意到客户端断开连接,而是一直等待服务器回复或断开连接。

为了解决这个问题,它需要同时从服务器(请求)和客户端(self.conn)套接字读取数据。要做到这一点,最简单的方法是使用非阻塞套接字。

票数 0
EN

Stack Overflow用户

发布于 2011-02-22 01:33:56

HTTP spec声明(第9.4节)

HEAD方法与GET相同,只是服务器不能在响应中返回消息体。

这意味着CRLFCRLF之后没有任何内容,但您的代理正在等待数据,而不是从传入的连接中读取数据。我怀疑couchdb库正在尝试使用保持活动的连接,但是您查看的套接字是错误的。

你的基本问题是,你声称与HTTP1.1对话,但你没有,你应该注意一个CRLFCRLF序列,一个content-size头。如果你发现有一个读取了那么多数据,那么就中断循环,如果没有一个,就立即中断。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5067636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档