이벤트 루프란 무엇일까?
1.쓰레드(thread)
이벤트 루프는 여러가지 데이터를 동시에 처리하기 위해 필요하다.
이를 이해하기 앞서 쓰레드(thread)에 대한 개념을 공부하겠다.
[제어판] - [시스템 및 보안] - [시스템]으로 이동한다.
여기서 cpu의 모델명을 보고 검색해보면 코어의 수를 알 수있고 한개의 코어당 두개의 쓰레드를 가지고 있다.
여러개의 쓰레드를 이용해 데이터를 분산시키면 더 빠르게 데이터 처리를 할 수 있다.
예를들어 데이터 1000개를 처리해야할 경우 쓰레드가 1개라면 혼자서 1000개를 처리하지만 쓰레드가 4개라면 각각 250개씩 나눠서 4배빠르게 결과를 얻을 수 있다. 이를 멀티 쓰레드 또는 다중 쓰레드라고 부른다.
지금 나는 주식 프로그램을 만드려고 하는데 멀티쓰레드 방식에는 '쓰레드의 간섭'이라는 문제가 있다.
멀티쓰레드를 이용하면 흩어져서 계산된 데이터 사이에서 서로 필요로 하는 부분을 공유해야하는데 이 과정에서 데이터가 누락될 위험도 있으며 진행 순서를 알기 어려워 데이터가 꼬이기도한다.
순차적으로 데이터처리를 하지만 동시에 처리하고 원하는 데이터를 우선 처리 할 수 있는 싱글 쓰레드 기반 이벤트 루프방식을 이용해야한다.
2.씽글 쓰레드의 이벤트 루프
우선 공간을 요청구간, 업무공간, 출력구간 세가지로 나누어서 생각해보겠다.
요청구간에서 코드를 작성한 뒤
업무공간(stack)으로 데이터를 보내 연산처리를 한다. 처리가 완료되면
출력구간인 콘솔에 결과값이 출력된다.
하지만 요청구간에 5초 후 A가 출력되는 함수와 바로 B출력되는 함수가 차례대로 있다고 하면
타이머가 지정한 시간이 지날때까진 업무공간에 들어온 요청은 처리되지 않는다.
여러 데이터를 다루는 프로그램에서는 두번째 함수를 출력하고 싶어도 기다려야하기 때문에 굉장히 치명적이다.
이를 해결하기 위해 프로그램의 생성, 읽기, 갱신, 삭제(CRUD)를 처리할 수 있는 WebAPI프레임워크가 등장했다.
아까와 같은 코드가 있다고 할 때
A를 업무공간에서 처리하지 않고 WebAPI프레임 워크에서 동작하도록 보낸다. 그리고 그 다음함수를 처리하는 업무는 업무공간에 들어가고 업무공간에는 앞서 실행되고 있는 데이터가 없기 때문에 바로 B가 출력될것이다.
WebAPI로 보내진 타이머는 5초가 지난 후 콜백 큐 공간에 처리된 결괏값이 쌓이게되고 업무공간에 더 처리할 데이터가 없는지 본다.
업무공간이 비어있다면 콜백큐에 쌓인 데이터를 업무공간으로 가져와 출력구간으로 보낸다.
이벤트 루프는 이 과정에서 업무공간이 비어있는지 확인&콜백공간으로 부터 출력구간으로 데이터 푸시를 하는 걸 말한다.
3.시그널, 슬롯, 이벤트
주식프로그램을 예로 들어 설명하자면
프로그래머가 호가창을 서버에 요청하면 서버는 요청 데이터를 처리한 다음 콜백큐공간에 호가창 결과를 넣어둔다.
그러면 이벤트루프를 통해 콜백큐에 담긴 호가창의 결과값을 가져올 수 있다.
시그널은 서버에 요청하는 신호를 뜻하고
슬롯은 요청한 데이터의 결과를 받을 공간을 말하며
이벤트는 시그널이 발생하면 결과를 어느 슬롯에서 받을 것인지 연결해주는 다리 역할을 한다.
즉 시그널을 보내고 결과가 큐에 쌓이면 이벤트 루프를 통해 슬롯에서 데이터를 반환받는 것이다.
4.QEventLoop()클래스
PyQt5에서 제공하는 QEventLoop()클래스를 사용하면 이러한 과정을 직접 구축하지 않고 코드 한줄로 가능하다.
이벤트 루프를 사용하지 않는다면 서버로 데이터를 보내고 난뒤 프로그램이 모든 역할을 끝낸줄 알고 요청한 데이터를 기다리지 않고 프로그램을 종료할 수 있다.
그렇기 때문에 이를 사용해 데이터 수신을하고 결과값을 반환받을 때까지 다음 작업으로 넘어가지 않고 기다릴 수 있게 되는 것이다.