2016-03-28 14 views
2

私は、time.sleep(x)を呼び出すと、コードを実行している現在のスレッドがx秒遅れることを理解しようとしています。しかし、それはx秒間プロセッサを解放するか、スレッドがリソースをそれ自体に保持し、x秒後に次のコード行の実行を開始します。私が直面しています正確なシナリオとtime.sleep()function

編集:

ここで私の場合です:このトルネードは正確にtime.sleep(5)何シングルスレッドのサーバになりますので、今

class SomeHandler(tornado.websocket.WebSocketHandler) 
    @tornado.gen.coroutine 
    def something_async(): 
    time.sleep(5) 
    return result 

    def on_message(message): 
    future = yield something_async(message) 

if __name__ == '__main__': 
    application = tornado.web.Application([ 
    (r'/', SomeHandler), 
    ]) 

    http_server = tornado.httpserver.HTTPServer(application) 
    http_server.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 

この場合(5秒間スレッドをブロックしてプロセス全体を同期させますか)、またはコルーチンが新しいスレッドを生成しますか?

+2

CPUを奪い、他のスレッドが実行されないようにするのは理にかなっていますか?おそらくあなたが見つけることができる方法はありますか? –

+3

おそらく、これはあなたを助けることができます:http://stackoverflow.com/questions/92928/time-sleep-sleeps-thread-or-process – Querenker

+0

単純な答えは、プロセッサを解放しますが、実装が異なる場合があります。待機時間が短くてもスレッドがCPUを保持する*スピンロック*と呼ばれる機能があります。具体的なAPIがあるWindowsでは、短いスリープ時間にスピンロックを使用することが考えられます。 http://stackoverflow.com/questions/7273474/behavior-of-pythons-time-sleep0-under-linux-does-it-cause-a-context-switchおよびhttp://stackoverflow.com/questions/も参照してください。 22115831/how-to-resolve-spinlock-issues-with-multithreaded-python – cdarke

答えて

3

の例では、常に最高です:

#!/usr/bin/env python 
# -*- coding: utf-8; py-indent-offset:4 -*- 
############################################################################### 
from __future__ import (absolute_import, division, print_function) 
#      unicode_literals) 

import threading 
import time 


def func1(): 
    time.sleep(10) 
    print('Func1: Out of sleep and returning') 


def func2(flag): 
    while not flag: 
     time.sleep(1) 
     print('Func2: looping') 

    print('Func2: Flag set, leaving') 


t1 = threading.Thread(target=func1) 
f = list() 

t2 = threading.Thread(target=func2, kwargs=dict(flag=f)) 

t1.start() 
t2.start() 

t1.join() 
f.append(None) 

出力で:

Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func2: looping 
Func1: Out of sleep and returning 
Func2: looping 
Func2: Flag set, leaving 

それはt1(第一スレッドが)の長いtime.sleepにブロックされている場合でも、出力から明白です10秒、2番目のスレッドt2が実行されています。

そしてt1が、我々は、メインスレッドがt2は、それが返すため、終了する必要があります理解させるためにflagとして使用されているリストにappendすることが可能であることを見て行われても。

So:time.sleepは、実行中のスレッドのみをブロックします。

+0

詳細な例をお寄せいただきありがとうございます。私はちょうど私がいる全体のシナリオを追加しました、あなたはそれについてコメントしていただけますか? –

+0

他の人からコメントをいただき、あなたの完全なコードを見ているように、問題はあなたがメインスレッドをブロックしていることです。 A. Jesse Jiryu Davisが提案したヒントを使用してください。 – mementum

2

*あなたがtime.sleepを呼び出すと、スリープ中にプロセス全体がブロックされます。他の処理は行われない。これは、文書が"time.sleep should not be used in coroutines because it is blocking"と言う理由です。明示的にコルーチンを一時停止し、IOLoopので、他の処理に制御を戻すに進むことができます:

yield gen.sleep(0.5) 

を*トルネードは、DNS解決場合、または明示的にタスクを非同期に行うためにThreadPoolExecutorを使用するためのスレッドを生成することができます。しかし、あなたはこの議論のためにこれらのケースを無視することができます。

+0

もう少し小さな問題です。既に値を返す関数でyield gen.sleep(0.5)を使用したいのですが? Python <3.3ではそれがサポートされていません。その場合は他に何ができるのですか? –

+0

Python 2のコルーチンから値を返すには、 "raise gen.Return(value)": http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.Return –

+0

私はまだ理解していない。説明する簡単な例を書くことができますか? ' def add(x、y): yield gen.sleep(countdown); a = x + y; raise gen.Return(a); この関数を呼び出して値を取得する方法は? –