asyncio로 비동기 처리하여 병렬처리 속도 높이기
파이썬(Python) 프로그래밍2021. 9. 12. 22:13
반응형
파이썬은 기본적으로 동기 방식으로 동작하는 언어이지만, 파이썬 3.4에서 asyncio가 표준 라이브러리로 추가되고,
파이썬 3.5에서부터는 async/await 키워드가 문법으로 채택이 되면서, 파이썬도 이제 언어 자체적으로 비동기 프로그래밍이 가능해 졌다.
예를 들어, 다음과 같이 선언된 함수는 동기 함수입니다.
def do_sync(): pass |
기존 def 키워드 앞에 async 키워드까지 붙이면 이 함수는 비동기 처리되며, 이러한 비동기 함수를 파이썬에서는 코루틴(coroutine)이라고도 부릅니다.
async def do_async(): pass |
이러한 비동기 함수는 일반 동기 함수가 호출하듯이 호출하면 coroutine 객체가 리턴됩니다.
do_async() # <coroutine object do_async at 0x1038de710> |
따라서 비동기 함수는 일반적으로 async로 선언된 다른 비동기 함수 내에서 await 키워드를 붙여서 호출해야 합니다.
async def main_async(): await do_async() |
async로 선언되지 않은 일반 동기 함수 내에서 비동기 함수를 호출하려면 asyncio 라이브러리의 이벤트 루프를 이용해야합니다.
loop = asyncio.get_event_loop() loop.run_until_complete(main_async()) loop.close() |
파이썬 3.7 이상에서는 다음과 같이 한 줄로 간단히 비동기 함수를 호출 할 수도 있습니다.
asyncio.run(main_async()) |
실제 저의 프로그램에 구현하기(goldstock 프로그램 일부 발췌)
import asyncio class Kiwoom(QAxWidget): def __init__(self): super().__init__() self.ui = SetupUI() self.realType = RealType() self.logging = Logging() self.slack = Slack() # 슬랙 동작 #중간생략... def auto_AI_recommend_clicked(self): now = datetime.now() if self.ui.btnCdtResult_buy.isChecked(): self.ai_recommend_timer_start() else: self.timer_ai_recommend.stop() return def ai_recommend_timer_start(self): self.timer_ai_recommend = QTimer() self.timer_ai_recommend.start(5 * 1000) # 5초 간격으로 self.timer_ai_recommend.timeout.connect(self.ai_recommend_click) def ai_recommend_click(self): market_status, decision_list = self.decide_to_autoTrading(stockCode) if market_status == "매수" or market_status == "강력매수": if self.ui.btnAutotrade.isChecked(): asyncio.run(self.decide_to_sell(1, stockCode)) asyncio.run(self.decide_to_sell(2, balance_detail_stockCode)) else: if (market_status == "매도" or market_status == "강력매도") and stockCode in self.account_stock_dict: if self.ui.btnAutotrade.isChecked(): asyncio.run(self.decide_to_sell(1, stockCode)) asyncio.run(self.decide_to_sell(2, balance_detail_stockCode)) async def decide_to_sell(self, num, stockCode): day_chart_data = {} minute_chart_data = {} week_chart_data = {} month_chart_data = {} recommInterval = str(self.ui.cbRecommInterval.currentText().replace(' ', '')) minute_chart_interval = str(self.ui.spinBox_minutes.value()) market_status, decision_list = self.decide_to_autoTrading_condtion2(stockCode=stockCode) if market_status in ("매도", "강력매도"): self.time_to_trading(order_currency=stockCode, type="매도", market_status="매도", \ current_price=current_price, target_time=recommInterval, date=order_date, real_flag="R", \ decision_list=decision_list) elif market_status in ("매수", "강력매수"): self.time_to_trading(order_currency=stockCode, type="매수", market_status="매수", \ current_price=current_price, target_time=recommInterval, date=order_date, real_flag="R", \ decision_list=decision_list) else: # 관망 pass def time_to_trading(self, order_currency="", type="", market_status="", target_units=0, current_price=0, \ target_time="", date="", real_flag="", decision_list=""): if type in ("매도", "강력매도"): # 매도 try: self.sendOrder("신규매도", order_currency, "시장가", int(possible_quantity), int(current_price)) except (ParameterTypeError, KiwoomProcessingError) as e: self.showDialog('Critical', e) return self.slack.notification(\ pretext="%s(%s) 시장가 매도주문 완료(로직No:%s)" % (stockName, order_currency, str_decision_list), title="%s 주문수량: %s 현재가: %s" % (self.now.strftime("%Y-%m-%d %H:%M:%S"), possible_quantity, \ current_price), text="https://finance.daum.net/chart/A%s" % order_currency) else: #매수주문 try: self.ui.pteLog.appendPlainText("%s(%s) (신규매수,시장가)주문전송" % (stockName, order_currency)) self.logging.logger.debug("%s(%s) (신규매수,시장가)주문전송" % (stockName, order_currency)) self.sendOrder("신규매수", order_currency, "시장가", int(target_units), int(current_price)) except (ParameterTypeError, KiwoomProcessingError) as e: self.showDialog('Critical', e) self.ui.pteLog.appendPlainText("%s(%s) 매수주문 오류발생" % (stockName, order_currency)) self.logging.logger.debug("%s(%s) 매수주문 오류발생" % (stockName, order_currency)) return # 거래내역 DB저장 self.insert_db_transaction_infos(self.not_account_stock_dict[self.orderNo]) # result |
이 프로그램에 실제 구현하여 동시성 병렬프로그램 함수 처리속도가 배가 빨라졌습니다.
이 기능에 대한 설명은 하기 사이트를 참조하였습니다. 감사합니다.
https://www.daleseo.com/python-asyncio/
반응형
'파이썬(Python) 프로그래밍' 카테고리의 다른 글
파이썬 개발을 도와주는 유용한 도구 IDE(Integrated Development Environment) (0) | 2022.01.16 |
---|---|
파이썬 주석 단축키가 먹히지 않을때 (0) | 2021.10.05 |
파이썬3 웹 크롤링 HTTP error 403 발생시 해결방법 (0) | 2021.04.07 |
ufunc 'add' did not contain a loop with signature matching types (dtype('<U170'), dtype('<U170')) -> dtype('<U170') (0) | 2021.03.27 |
파이썬에서 Slack API를 통한 주식매매정보 보내기 (0) | 2021.03.05 |
댓글()