#coroutine
sub-routine: 종속되어있는 루틴. 함수도 서브 루틴에 포함된다.
co-roution: 협력적으로 실행되는 루틴. 비동기 실행에서 사용된다. 실행중인 함수를 잠시 멈추고 나중에 실행을 재생할 수 있다.
# 서브루틴 예시
def func(a):
return a+1
a=1
b=func(a)
print(b)
서브루틴은 결국 순차적으로 처리되는 것이나 다름없다.(동기처리)
반대로 비동기 프로그래밍은 여러 작업을 동시에 처리할 수 있다.
코루틴 Vs. 멀티 스레딩
- 스레드는 운영체제에 의해 관리되면서 여러 작업을 수행하며 각 스레드는 메모리상에서 자체 스택을 가지고 있어서 독립적인 흐름을 가진다.
멀티 프로세싱에 비해 오버헤드가 적고 자원 공유가 쉽지만 공유하는 자원으로 인해 동기화 문제를 고려해야한다. - 코루틴은 언어차원에서 제공되는 기능이며 코루틴 객체를 스위칭하는 것을 통해 비동기 작업의 동시성(concurrency)를 구현할 수 있다. 코루틴은 스레드보다 더 가볍고, 빠르며, 동기화 문제가 발생하지 않고, 스위칭 시점을 프로그래머가 직접 지정할 수 있으나, 하나의 스레드 상에서 실행하는것이 권장된다.
병렬성은 멀티 스레딩으로 얻어야하며 코루틴은 스레드의 대안이 아닌, 스레드를 더 쪼개 쓰기위한 방법이라고 할 수 있다.
스레드는 I/O-bound작업(CPU연산 보다 입출력으로 인한 대기시간이 더 긴 작업) 및 병렬처리, 코루틴은 I/O-bound작업 및 비동기 이벤트 처리에 사용한다.
파이썬 코루틴
파이썬이 기본적으로 제공하는 코루틴 기능으로, 일반적인 함수와 유사하지만 실행중인 함수를 일시중지 하고 나중에 다시 시작할 수 있는 기능
핵심키워드 | 설명 |
---|---|
yield | 만날때 마다 함수를 일시중단 후 반환할 값이 있다면 값을 반환한다. |
next | 다음 yield를 만날때까지 코루틴을 다시 시작 |
send | 코루틴에 값 전달해 다시실행. yield 반환값이 send함수의 인자가 된다. |
def my_coroutine():
while True:
value = yield # send 로부터 값 받음
print("Received value:", value)
# 코루틴 객체 생성
co = my_coroutine()
# 코루틴 실행 준비 - 첫 yield 전까지 실행
next(co)
# 값을 보내기
co.send("Hello, world!") # Received value: Hello, world!
co.send("hi, world!") # Received value: hi, world!
co.send("bye, world!") # Received value: bye, world!
def my_generator():
yield 1 # yield로 반환
yield 2
yield 3
gen = my_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
Q:iterable 하면 next()를 쓸수 있다고 알고 있습니다. 코루틴은 iterable한 객체 인건가요?
A: 맞습니다. 위 예시코드의 2번째 형식의 coroutine객체는 제너레이터라고도 불리며 for문에도 사용가능한 iterable한 객체입니다.
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
for i in gen:
print("in for",i) # in for 1,in for 2, in for 3
Asynco
비동기 프로그래밍을 위한 라이브러리fh, 상태를 자동 관리하여 편리하고 안전하게 동시성을 구현할 수 있다.
키워드 | 설명 |
---|---|
async | 코루틴 선언 |
await | 코루틴 안에서 다른 코루틴의 실행완료를 기다림 - 꼭 그 작업이 끝나야 실행이 가능할 때 |
run() | 코루틴을 시작한다. |
## 예시 코드 | |
```python | |
import asyncio | |
import random |
async def fetch_data():
print("데이터를 가져오는 중...")
await asyncio.sleep(1) # 데이터를 가져오는데 1초가 걸린다고 가정
return random.randint(1, 100)
동시에 실행될 필요가 있지만
결국 코루틴의 결과가 필요한경우
async def main():
data = await fetch_data()
print(f"가져온 데이터: {data}")
실행 시작
asyncio.run(main())
```
레퍼런스
https://velog.io/@haero_kim/Thread-vs-Coroutine-%EB%B9%84%EA%B5%90%ED%95%B4%EB%B3%B4%EA%B8%B0
https://sogummi.tistory.com/99
'Python' 카테고리의 다른 글
재귀 & 추상클래스 (0) | 2023.05.01 |
---|---|
객체지향 프로그래밍 (0) | 2023.05.01 |
파이썬 패키지 관리 (0) | 2023.04.26 |
프로세스,스레드,멀티프로세싱, 멀티 스레딩 (0) | 2023.04.25 |
각 타입별 중요 메소드 (0) | 2023.04.24 |