使用threading.Event在python中同步任务

时间:2018-04-11 12:45:36

标签: python multithreading python-3.x

import socketserver
from http.server import SimpleHTTPRequestHandler
from threading import Timer, Event
from urllib.request import urlopen

class Responder( SimpleHTTPRequestHandler ):
    evt = Event(  )

    def do_GET( self ):
        print( 'req:', self.path )

        if self.path == '/block':
            Responder.evt.wait(  )
            self.respond( self.path )

        elif self.path == '/unblock':
            Responder.evt.set(  )
            self.respond( self.path )

        else:
            pass
            # self.respond( self.path )

    def respond( self, response ):
        self.send_response( 200 )
        self.send_header( 'Content-type', 'text/plain' )
        self.end_headers(  )
        self.wfile.write( bytes( str( response ), 'utf8' ) )

# create and start server
httpd = socketserver.TCPServer( ( '', 80 ), Responder )
Timer( 0, lambda: httpd.serve_forever(  ) ).start(  )

# just request the stated URL
def req_async( url, sec_delay = 0 ):
    Timer( sec_delay, lambda: print( 'resp:', urlopen( url ).read(  ) ) ).start(  )

req_async( 'http://localhost/block', 1 )
req_async( 'http://localhost/unblock', 2 )

req_async( 'http://localhost/foo' ) # closed connection without response !! but ..
# .. why not keep response stream open till I decide to write something on it ..
# .. or close it ?!

print( 0 )
This program creates a local server on port 80,
and requests that server to
    (1) block after 1 second, and
    (2) unblock after 2 seconds.

The class Responder has one threading.Event object,
    Responder.evt,
which I want other requests to block/unblock on.

When I get request on /block path, I wait on evt.
When I get request on /unblock path, I release waiters.

But only request (1) gets honored, and (2) is nowhere
in the scenes :D
Is it because (1) has blocked the server thread ?!
Is it because evt is shared ?

Can someone tell what happens there and why ?! TY ! :)

And also, how to properly do this in case it does block
the server thread.

And also see the (3)rd request .. how to keep the
response stream open ?

So, all in all,
    [1] why python doesn't keep response stream open ? and
    [2] why request (2) is not getting logged ?

Thank you and regards,
Ankur

1 个答案:

答案 0 :(得分:0)

首先,我应该使用BaseHTTPRequestHandler代替SimpleHTTPRequestHandler来实现处理程序。

其次,要回答[2],上述两个类都将处理 一次只有一个请求。因此,请在上述程序中请求(2) 在处理(1)之前无法处理,但由于(1)被阻止, (2)无法记录。

要使上述处理程序具有多线程,请参阅this answer

第三,回答[1],我仍然不确定,但我想是的 表现得像这样:

如果do_GET / do_POST没有返回 写一个响应,然后我猜处理程序关闭响应流。