2015-08-17 25 views
0

我有一個相當大的基於扭曲的應用程序。某處有一些代碼會在主線程中執行太多計算,從而導致延遲尖峯。我想把它放到後臺線程中,但我必須先找到罪魁禍首。什麼阻止我的主線程?

具有一個扭轉的任何工具來幫助我追查在主線程持有嗎?

扭曲應該能夠如果線程沒有在幾毫秒內恢復,然後幫我找出什麼是保持忙碌線程的通知。例如通過轉儲主線程的堆棧跟蹤。

回答

2

傑夫·格里爾有a tool called twisted_hang可以告訴你在哪裏扭曲的流程都掛。

+1

哈!正是我在找什麼。我昨天一起黑了一些非常相似的東西(儘管使用後臺線程和sys._current_frames而不是信號)。很高興看到我不是唯一一個沒有骯髒黑客而無法做到這一點的人:) – Stefan

1

運行:

[email protected]:~/Desktop/toy_problems/twisted$ twistd -n -y hello_world.tac --profile=pstats_obj --profiler=cprofile --savestats 
2015-08-17 06:52:23-0500 [-] Log opened. 
2015-08-17 06:52:23-0500 [-] twistd 14.0.2 (/usr/bin/python 2.7.9) starting up. 
2015-08-17 06:52:23-0500 [-] reactor class: twisted.internet.epollreactor.EPollReactor. 
2015-08-17 06:52:23-0500 [-] Site starting on 8000 
2015-08-17 06:52:23-0500 [-] Starting factory <twisted.web.server.Site instance at 0x7f81e54002d8> 
2015-08-17 06:52:35-0500 [HTTPChannel,0,127.0.0.1] "127.0.0.1" - - [17/Aug/2015:11:52:34 +0000] "GET/HTTP/1.1" 200 53 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36" 
2015-08-17 06:52:35-0500 [HTTPChannel,0,127.0.0.1] "127.0.0.1" - - [17/Aug/2015:11:52:35 +0000] "GET /favicon.ico HTTP/1.1" 200 64 "http://localhost:8000/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36" 
^C2015-08-17 06:52:40-0500 [-] Received SIGINT, shutting down. 
2015-08-17 06:52:40-0500 [-] (TCP Port 8000 Closed) 
2015-08-17 06:52:40-0500 [-] Stopping factory <twisted.web.server.Site instance at 0x7f81e54002d8> 
2015-08-17 06:52:40-0500 [-] Main loop terminated. 
2015-08-17 06:52:40-0500 [-] Server Shut Down. 
[email protected]:~/Desktop/toy_problems/twisted$ 

然後:

從終端
twistd -n -y hello_world.tac --profile=pstats_obj --profiler=cprofile --savestats 

輸出

import pstats 
s = pstats.Stats('pstats_obj') 
s.sort_stats('time') 

或者你也可以不--savestats運行:twistd -n -y hello_world.tac --profile=pstats_obj --profiler=cprofile

 508 function calls (501 primitive calls) in 0.036 seconds 

Ordered by: standard name 

ncalls tottime percall cumtime percall filename:lineno(function) 
    8 0.000 0.000 0.000 0.000 :0(abs) 
    4 0.000 0.000 0.000 0.000 :0(acquire) 
    2 0.000 0.000 0.000 0.000 :0(add) 
    15 0.000 0.000 0.000 0.000 :0(append) 
    12 0.000 0.000 0.000 0.000 :0(callable) 
    2 0.000 0.000 0.000 0.000 :0(clear) 
    6 0.000 0.000 0.000 0.000 :0(copy) 
    8 0.000 0.000 0.000 0.000 :0(fcntl) 
    3 0.000 0.000 0.000 0.000 :0(fileno) 
    4 0.000 0.000 0.000 0.000 :0(flush) 
    4 0.000 0.000 0.000 0.000 :0(fromtimestamp) 
    2 0.000 0.000 0.000 0.000 :0(get) 
    9 0.000 0.000 0.000 0.000 :0(get_ident) 
    5 0.000 0.000 0.000 0.000 :0(getattr) 
    1 0.000 0.000 0.000 0.000 :0(getsignal) 
    2 0.000 0.000 0.000 0.000 :0(gmtime) 
    2 0.000 0.000 0.000 0.000 :0(hasattr) 
    3 0.000 0.000 0.000 0.000 :0(heappop) 
    4 0.000 0.000 0.000 0.000 :0(heappush) 
    21 0.000 0.000 0.000 0.000 :0(isinstance) 
    1 0.000 0.000 0.000 0.000 :0(iter) 
    4 0.000 0.000 0.000 0.000 :0(join) 
    18 0.000 0.000 0.000 0.000 :0(len) 
    4 0.000 0.000 0.000 0.000 :0(map) 
    5 0.000 0.000 0.000 0.000 :0(max) 
    5 0.000 0.000 0.000 0.000 :0(min) 
    1 0.000 0.000 0.000 0.000 :0(pipe) 
    5 0.000 0.000 0.004 0.001 :0(poll) 
    16 0.000 0.000 0.000 0.000 :0(pop) 
    4 0.000 0.000 0.000 0.000 :0(range) 
    2 0.000 0.000 0.000 0.000 :0(read) 
    1 0.000 0.000 0.000 0.000 :0(register) 
    4 0.000 0.000 0.000 0.000 :0(release) 

# from twisted.internet import reactor 
from twisted.application import service, internet 
from twisted.web import static, server 
from twisted.web.resource import Resource 

class Hello(Resource): 

    def getChild(self, name, request): 
     return self 

    def render_GET(self, request): 
     return '<html>Hello, GET world! I am located at %r. </html>' \ 
       % (request.prepath) 

def getWebService(): 
    """ 
    Return a service suitable for creating an application object. 
    """ 
    site = server.Site(Hello()) 
    # site = server.Site(Hello()) 
    # reactor.listenTCP(8000, site) 
    # reactor.run() 
    return internet.TCPServer(8000, site) 

# this is the core part of any tac file, the creation of the root-level 
# application object 
application = service.Application("Hello application") 

# attach the service to its parent application 
service = getWebService() 
service.setServiceParent(application) 

這裏是「hello_word.tac」:

# from twisted.internet import reactor 
from twisted.web import static, server 
from twisted.web.resource import Resource 
from twisted.application import service, internet 

class Hello(Resource): 

    def getChild(self, name, request): 
     return self 

    def render_GET(self, request): 
     return '<html>Hello, GET world! I am located at %r. </html>' \ 
       % (request.prepath) 

def getWebService(): 
    """ 
    Return a service suitable for creating an application object. 

    This service is a simple web server that serves files on port 8080 from 
    underneath the current working directory. 
    """ 
    site = server.Site(Hello()) 

    return internet.TCPServer(8000, site) 

# this is the core part of any tac file, the creation of the root-level 
# application object 
application = service.Application("Hello application") 

# attach the service to its parent application 
service = getWebService() 
service.setServiceParent(application) 

一旦成型,那麼你可以添加一個裝飾添加某種(逐行)的鉤來分析所佔用的通話很多時間。

+0

我試着在過去進行分析,並沒有設法找到它的瓶頸。我沒有深入研究過,但似乎扭曲的異步本質並不適合剖析,特別是@inlineCallbacks如果我沒有記錯的話會導致一些奇怪的結果。不過,我並沒有扭動它。 – Stefan