python event example

 python threading 모듈의 Event는 Thread간 정보를 주고받을 수 있는 가장 간단한 도구라고 할 수 있다.

threading.Event의 메소드는 다음과 같다.

is_set() : 이벤트 flag가 True인경우, True를 반환
set() : 이벤트 flag를 True로 설정
clear() : 이벤트 flag를 False로 설정
wait(time=None) : 이벤트 flag가 True가 될 때까지 기다린다. timeout 단위는 초(seconds)


1. asyncio server socket에서의 사용 예

아래 포스트의 서버 예제에 Event Object를 추가했다.

python asyncio를 이용한 async socket server client example code


import asyncio
import threading

server_close_event = threading.Event()
    
async def handle_asyncclient(reader, writer):
    print('client :', writer.get_extra_info('peername'))
    while True:
        data = await reader.read(8)
        if data == b'ping':
            writer.write(b'pong')
            await writer.drain()
            print('recv: ping -> send: pong')
        elif data == b'done':
            print('recv: done')
            break
        elif len(data) == 0:
            break
    
    writer.close()
    await writer.wait_closed()
    server_close_event.set()
    print('connection was closed')

async def server_asyncmain():
    server_close_event.clear()
    server = await asyncio.start_server(handle_asyncclient,'localhost',8000)  
    if server is not None:
        print('server started')
        #
        while server_close_event.is_set() is False:
            await asyncio.sleep(1)

        server.close()
        await server.wait_closed()
        print('server was closed')


if __name__ == "__main__":
    
    try:
        loop = asyncio.get_running_loop()
    except RuntimeError:
        loop = None
    
    if loop and loop.is_running():
        print('Async event loop already running')
        tsk = loop.create_task(server_asyncmain())
    else:
        print('Starting new event loop')
        asyncio.run(server_asyncmain())  


threading.Event 객체를 생성하고, handle_asyncclient에서 클라이언트와의 통신이 종료되면 이벤트를 발생시킨다.  server_asyncmain에서 이벤트를 기다리며, 이벤트가 발생하면 서버를 종료하도록 했다.

[Note] asyncio app에서 threading.Event.wait()를 사용할 경우 async loop가 멈춰버려 서버가 정상적으로 동작하지 않는다. 


2. Thread에서 사용 예

get_event_thread에서는 이벤트가 발생하면 Thread를 종료하고, set_event_thread에서는 5초간 대기 후 이벤트를 발생시키는 예제 코드이다.


import threading

class set_event_thread(threading.Thread):
    
    event=None
    
    def set_eventobj(self, Event):
        self.event = Event
        
    def run(self):
        if self.event == None:
            return
        print('set_event_thread started:',time.ctime())
        time.sleep(5)
        print('event.set:',time.ctime())
        self.event.set()
       
class get_event_thread(threading.Thread):
    
    event=None
    
    def set_eventobj(self, Event):
        self.event = Event
        
    def run(self):
        if self.event == None:
            return
        print('get_event_thread started:',time.ctime())
        self.event.wait()
        print('event.wait done:',time.ctime())
        
        
def wait_event_main():
    
    event = threading.Event()
    event.clear()
    
    set_th = set_event_thread(name='set event thread',daemon=True)
    get_th = get_event_thread(name='get event thread',daemon=True)
    
    set_th.set_eventobj(event)
    get_th.set_eventobj(event)
    
    get_th.start()
    set_th.start()
    
    if set_th.is_alive():
        set_th.join()
    
    if get_th.is_alive():
        get_th.join()


실행 결과

get_event_thread started: Wed Aug 19 13:47:51 2020
set_event_thread started: Wed Aug 19 13:47:51 2020
event.set: Wed Aug 19 13:47:56 2020
event.wait done: Wed Aug 19 13:47:56 2020


관련 포스트

python thread example

댓글

이 블로그의 인기 게시물

간단한 cfar 알고리즘에 대해

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

base64 인코딩 디코딩 예제 c 소스

간단한 칼만 필터(Kalman Filter) 소스 코드와 사용 예제