티스토리 뷰

Python 잡지식

Event Listener의 정체

Teus 2021. 3. 10. 08:00
728x90
반응형

이번 포스팅은 Event Listener의 정체입니다.

 

많은분들이 코딩을 배우면서, 반응형 System(Web, Application...)을 배우면서

 

Event Listener에 대해서 배우게 됩니다.

 

Event Listener는 Event(사용자의 Click or 키보드 입력 등.... Not normal한 상태)가 발생할 경우

 

해당 행동을 인지하고, 사용자에게 결과를 반환해 줍니다.

 

설명을 잘 살펴보면

1. 사용자의 특정 입력을 받는다.

2. 해당 입력이 무엇인지 판단한다.

3. 입력에 따라 정해진 결과를 반환한다.

함수의 구조와 매우 유사한 것을 알 수 있습니다.

함수와 Event Listener의 비교

그렇다면, 함수를 이용해서 아래와같은 Event Listener를 만들 수 있을 것입니다.

def listener_left():
    while True:
        #win32api.GetKeyState(0x01) => 마우스 좌클릭이
        #Click되었을 경우 -127을 반환하는 window api입니다.
        if win32api.GetKeyState(0x01)==-127:
            print("left_listener_end")
            break

listener_left()

a = 1
b = 5
a = a+b
print(a)

위 경우 마우스 좌클릭이 되기 전까지 계속 Listener_left 함수가 실행되면서

 

함수가 Event Listener와 같은 역할을 하는것 처럼 보입니다.

 

문제는 Event Listener가 실행되면서, 우리는 다른 작업이 동시에 이뤄지기를 바랍니다.

 

하지만 위 Case는 Listener_left가 실행되는 동안 아래의 print(a)까지 실행이 불가능 하고,

 

결국 중간에 작업이 막히게 되는 결과를 보여줍니다.

(이를 blocking 이라고 합니다)

 

 

 

이때 지난포스팅에서 다뤘던 Thread가 등장합니다.

 

Thread를 사용했을 때와 안했을때의 listener_left 함수의 상황(분기 위치에서 listener_left 함수 실행)

Thread없이 listener_left 함수를 실행시키면 해당 함수의 종료가 Main_thread에서 필요하기 때문에

 

함수가 종료되기 전까지 다음 실행이 불가능한 장판파가 되어 Program의 흐름이 막히게 됩니다.

 

하지만, Thread를 사용하면 상황이 달라집니다.

 

Thread를 사용할 경우, 다중 Thread가 동시에 실행되게 됩니다.

 

그러면 Main_thread가 흘러가면서, 동시에 listener_left함수가 실행되고 있는 상황이 가능합니다.

 

==> background에서 listener_left 함수가 계속 실행되고 있기 때문에, 

       Event listener가 되어 계속 Event의 발생 여부를 확인하게 됩니다.

 

Thread와 Multiprocessing을 포스팅하면서, Thread의 활용처가 애매하다고 생각했는데

 

시분할을 통해서 여러 작업을 동시에 돌리는 것이 Event Listener의 구현에 사용되는게 재미있네요 

 

Python으로 구현해본 left, right click을 감지하는 Event Listner입니다 :)

import threading
import win32api


def listener_left():
    while True:
        #win32api.GetKeyState(0x01) => 마우스 좌클릭이
        #Click되었을 경우 -127을 반환하는 window api입니다.
        if win32api.GetKeyState(0x01)==-127:
            print("left_listener_end")
            break
        
def listener_right():
    while True:
    	#win32api.GetKeyState(0x02) => 마우스 우클릭이
        #Click되었을 경우 -127을 반환하는 window api입니다.
        if win32api.GetKeyState(0x02)==-127:
            print("right_listener_end")
            break
        
#좌클릭을 Listening하는 10개의 Thread 실행        
for i in range(10):
    t = threading.Thread(target = listener_left)
    t.start()
#우클릭을 Listening하는 10개의 Thread 실행
for i in range(10):
    t = threading.Thread(target = listener_right)
    t.start()

print("real end")
'''
Result[0]
#Event Listener가 끝나기 전에 Main Flowr가 종료됨
real end
#좌클릭이 발생해서 좌클릭을 인식하고 10개의 Thread가 종료
#이때 해당 Thread에서 실행중이 함수만 실행되고
#Main Flow로 돌아오지 않습니다(real end가 출력이 안됨)
left_listener_end
left_listener_end
left_listener_end
left_listener_end
left_listener_end
left_listener_end
left_listener_end
left_listener_end
left_listener_end
left_listener_end
#우클릭이 발생해서 우클릭을 인식하고 10개의 Thread가 종료
#이때 해당 Thread에서 실행중이 함수만 실행되고
#Main Flow로 돌아오지 않습니다(real end가 출력이 안됨)
right_listener_end
right_listener_end
right_listener_end
right_listener_end
right_listener_end
right_listener_end
right_listener_end
right_listener_end
right_listener_end
right_listener_end
728x90
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함