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)를 통해 윈도우 화면 미러링 방법

mkfs.fat Device or resource busy 에러 해결법

python winsound를 이용한 윈도우 환경에서 소리 재생 예제

Embedded Linux USB Ethernet Gadget 사용하기