본문 바로가기
언어 정리/python_비동기관련_lib

asyncIO_2_( asyncIO개념(Idle state, I/O wait,I/O연산) + 함수 : gather )

by 알 수 없는 사용자 2022. 4. 20.

 

참고

https://realpython.com/async-io-python/#setting-up-your-environment

듀토리얼사이트

 

https://realpython.com/python-concurrency/

싱글쓰레드 , asyncio , 멀티프로세싱 차이에 대한 글

 

https://ko.wikipedia.org/wiki/%EC%9C%A0%ED%9C%B4_(CPU)

idle 이란


https://stackoverflow.com/questions/35835219/is-this-multi-threaded-function-asynchronous


I/O Wait 란 : (I/O를 Wait 한다 정도의미)

Percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request.

시스템에 미결 디스크 I/O 요청이 있는 동안 CPU 또는 CPU가 유휴 상태였던 시간의 백분율입니다

 

 

유휴 상태 란 :

사전적의미는 idle == 유휴 == 쉬는상태

 

idle 이란 :

컴퓨터 처리 장치에서 유휴 상태(idle state)은 어떠한 프로그램에 의해서도 사용되지 않는 상태를 말한다.

컴퓨터 시스템 위에서 실행되는 모든 프로그램, 태스크는 CPU에서 특정한 양의 처리 시간을 차지한다. CPU가 모든 태스크를 끝내면 유휴 상태가 된다.

근데 보통 I/O 연산보다 CPU연산이 훨 빠르기 때문에 CPU가 모든task 를 끝내고 I/O연산을 기다리고 있는데 이 상태가 idle state이다.

idle 쓰는 이유 :

현대의 프로세서들은 유휴 시간을 사용하여 전원을 절약한다. 공통적인 방식은 CPU 전압과 함께 클럭 속도를 낮추는 것, 그리고 프로세서의 일부를 슬립(sleep) 상태로 보내는 것이다. x86 HLT 명령어와 같은 인터럽트가 발생하기 전까지 CPU를 중단하는 중단(Halt) 명령을 가진 프로세서에서는 유휴 태스크가 HLT 명령 실행을 반복하는 루프로 구성되어 있을 경우 상당한 양의 전원과 발열을 절약할 수 있다.

idle 어떻게 실행되나 ( OS스케줄러 ) :

마이크로소프트 윈도우,[1] 리눅스,[2], macOS[3] 등의 수많은 운영 체제들은 CPU가 할 일이 없을 때 CPU에서 OS 스케줄러에 의해 적재되는 특수한 태스크인 유휴 태스크(idle task)를 실행한다. 이 유휴 태스크는 스케줄러에 하드 코딩을 할 수 있으며, 아니면 잠재적으로 가장 낮은 우선 순위의 별개의 태스크로 구현이 가능하다. 후자 방식의 장점은 시스템 상태를 모니터링하는 프로그램이 다른 모든 태스크와 더불어 유휴 태스크를 볼 수 있다는 것이다. 한 예로 윈도우 NT 시스템 유휴 프로세스를 들 수 있다.

 

I/O연산 이란 :

컴퓨터에서 연산을 한다는 것은 CPU가 무언가 일을 한다는 뜻이다.

  • 입출력 장치들의 I/O 연산 - I/O 컨트롤러가 담당
  • 컴퓨터 내에서 수행되는 연산 - 메인 CPU가 담당

이 때, 입출력 장치(I/O)와 메인 CPU는 동시 수행이 가능하다.  

프로그램 B : CPU 할당 받고 프로그램 코드 수행중				// CPU 연산
프로그램 A : 하드디스크에서 정보를 읽어오는 작업 수행중	  		// I/O 연산
➜ 두가지 일이 다른 곳에서 발생하므로 동시에 수행 가능

로컬 버퍼(local buffer) 

  • 장치 컨트롤러에는 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리ex) 디스크나 키보드 등에서 데이터를 읽어오는 경우, 우선 로컬 버퍼에 데이터가 임시로 저장된 후 메모리에 전달된다.

 

결론 :

I/O연산은 CPU연산보다 느리고 각각의 리소스(연산하는데 소모되야하는 자원)도 다르다 ->

main thread 에서 프로그램을 순차적으로 진행하다 보면 I/O 연산 과정에서 CPU 쪽에 idle state이 발생(I/O wait) ->

여기서 "idle state 에서 대기하는 시간을 줄이면 연산속도 증가한다"가 됨 ->

idle state(I/O wait)일 때 프로그래밍적으로 그 지점을 기억해 두고(buffer에 저장하는것 처럼) ->

idle state동안에는 다른 연산을 수행할 수 있도록 해서 총 시간을 줄여 주는게 asyncio이다.

 


이 튜토리얼은 비동기 IO에 대한 Python의 접근 방식을 보다 확실하게 이해할 수 있도록 해당 질문에 답하는 데 도움이 되도록 제작되었습니다.

다룰 내용은 다음과 같습니다.

  • 비동기식 IO(비동기식 IO) : 여러 프로그래밍 언어에서 구현되는 언어에 구애받지 않는 패러다임(모델)
  • async/await : 코루틴을 정의하는 데 사용되는 두 개의 새로운 Python 키워드
  • asyncio: 코루틴을 실행하고 관리하기 위한 기반과 API를 제공하는 Python 패키지

코루틴(특수 생성기 함수)은 Python에서 비동기 IO의 핵심이며 나중에 자세히 살펴보겠습니다.

 

await 의 의미 : awaitable 한 객체이다. 라는 의미


----------------------------내가 따로 정리-------------------------------

 main 에서 async def 함수 2개 조절하는거

 

"await asyncio.sleep(1)" 함수로 슬립하는 순간 idle 타임이 생기고 그타이밍에 "await asyncio.sleep(1)" 슬립하고 있지 않는 순으로 다른 함수를 호출함.

이부분 같은 경우엔 async def aa() 함수 실행되고나서 --> bb() --> cc() --> aa() 순으로 실행되고난 후에도 bb() 와 cc() async 함수가 sleep 상태이기 때문에 aa() 함수가 한번 더 실행되는 경우다.


------------------------------인프런강의---------------------------------

1.

asyncIO 사용 , 단일쓰레드 , 1초걸림

non-blocking 형식임. one 하고 1초 기다리는 동안 옆에 함수 실행한거.

await asyncio.gather( 함수(),함수(),~~ ) 코루틴 테이블에 등록할 함수들 

await asyncio.sleep( int ) 코루틴 테이블에 등록된 함수에서만 사용될 지연타이머함수

그래서 -> await asyncio.sleep(1) 대신에 timer.sleep(1) 쓰면 동기프로그램처럼 3초걸림

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.

 

2

asyncIO 사용 X , 단일쓰레드 , 3초걸림

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
$ python3 countsync.py
One
Two
One
Two
One
Two
countsync.py executed in 3.01 seconds.

 


 

댓글