SlideShare une entreprise Scribd logo
1  sur  146
Télécharger pour lire hors ligne
Python 동시성/병렬성 
DEVIEW 2014 
정민영 @ 비트패킹컴퍼니
발표자 
• 정민영 
• 미투데이 / 비트패킹컴퍼니 
• 07년 Nginx를 만난 후 비동기 덕후 
• kkung@beatpacking.com
우리는
매우 사랑하긴 하지만…
def calc(): 
return max([random() for x in 
xrange(20000000)]) 
! 
if __name__ == '__main__': 
print(calc()) 
print(calc()) 4.418s
if __name__ == '__main__': 
threads = [] 
for i in xrange(2): 
threads.append(threading.Thread(target=calc)) 
threads[-1].start() 
for t in threads: 
t.join() 
7.683s
가끔은…. 당황!
왜 thread가 더 느리지?
Global Interpreter Lock
Thread 1
Thread 1 
Thread 2
Thread 1 
Thread 2 
Thread 3
Thread 1 
Thread 2 
Thread 3 
3개의 Python thread가 수행되고 있는 상태에서, 
Thread 1이 수행되고 있는 상황의 예를 보겠습니다.
Thread 1 
Thread 2 
Thread 3 
I/O
Thread 1 
Thread 2 
Thread 3 
I/O 
release GIL
Thread 1 
Thread 2 
Thread 3 
I/O 
release GIL 
acquire GIL
Thread 1 
Thread 2 
Thread 3 
I/O 
release GIL Context Switch 
acquire GIL 
Python은, I/O(/System call)이 발생하게 되면, 
thread는 GIL을 해제하게 되고, 다른 GIL을 획득 하는 
thread로 제어권이 넘어갑니다.
Thread 1 
Thread 2 
Thread 3 
I/O 
release GIL Context Switch 
acquire GIL 
Python은, I/O와 같은 경우 처럼 Python 객체를 
건드리지 않고, 계속 수행할 필요가 있을 경우 
Py_BEGIN_ALLOW_THREADS 를 통해서, 계속 
thread를 수행하게 할 수 있습니다.
또한, system call뿐만 아니라, Python byte code 
상에서 100개가 실행될 때마다도 마찬가지로 GIL을 
해제함으로써, 다른 thread로 제어권을 넘기게 됩니다. 
Thread 1 
Thread 2 
Thread 3 
I/O 100 tick 
release GIL C/S 
acquire GIL
Python은 사실상 
Single Thread 
따라서, Python은 threading 모듈을 통해서 여러 thread 
를 생성할 수 있음에도 불구하고, 사실상 GIL에 의해서 예 
외적인 경우를 제외하고, 한 시점에는 하나의 thread만 작 
동하는 것 처럼 보이게 됩니다.
I/O는 되는거 아닌가요?
Thread 1 
Thread 2 
Thread 3 
I/O I/O
Thread 1 
Thread 2 
Thread 3 
I/O I/O
Thread 1 
Thread 2 
Thread 3 
I/O I/O 
C/S ? 
System call에 의해서 GIL을 획득하지 못한 thread가 계속 수행되는 
경우에도, system call이 종료되고 python 코드를 수행하기 위해서는 
GIL을 획득해야하기 때문에, 원하는 시점에 thread가 제어권을 다시 획 
득하는 보장이 없습니다.
장담할 수 없음!
Implicit Scheduling
어떤 thread로 
넘어갈지는 사실상 랜덤 
Python은 별도의 thread 스케쥴링 없이, 시스템이 제공하는 
threading library의 lock mechanism에 의해서 문맥이 전환됩니다.
그럼, GIL은 
무조건 나쁜가요?
그건 아닙니다.
(상대적으로) 단순한 구현 
적은 버그와 용이한 구현
single thread 
성능에 우위 
Python은 memory 관리를 reference counting의 방법으로 하는데, 
GIL에 대비되는 fine-grained lock방법을 사용할 경우 모든 객체의 접 
근마다 lock 으로 관리해야 하므로 그 overhead가 매우 큽니다.
C 확장 개발에 용이
더 많은 일을 
빠르게 처리하려면?
일?
CPU BOUND
수행시간에 
CPU가 더 영향이 큰 작업
압축, 정렬, 인코딩, ….
I/O BOUND
수행시간에 
I/O가 더 영향이 큰 작업
네트워크, 디스크, ….
대부분의 WEB APP!
이런 일을 
더 많이, 더 빠르게
동시성을 높인다
병렬성을 높인다
동시성? 병렬성?
같은말 아닌가요?
동시성 ≠ 병렬성
PARALLELISM
CONCURRENCY
CPU BOUND 
병렬성으로 UP
I/O BOUND 
동시성으로 UP
그럼 python은 
병렬성은 물건너 갔나요?
“(…) If you want your application to make 
better use of the computational 
resources of multi-core machines, you 
are advised to use multiprocessing. (…)” 
https://docs.python.org/2/library/threading.html
multiprocessing
Fork
if __name__ == '__main__': 
processes = [] 
for i in xrange(2): 
processes.append(multiprocessing.Process(target=calc)) 
processes[-1].start() 
p.join() 2.431s 
for p in processes:
multiprocessing 모듈은, fork를 통해서 동시에 여러 
프로세스에 원하는 작업을 실행할 수 있도록 도와주는 
모듈입니다. 앞서 예제 코드를 실행할 경우, main 
process를 포함해서 추가로 2개의 프로세스가 작동하 
여 병렬화 되는 모습을 확인할 수 있습니다.
Queue / Pipe
Lock
Shared Memory / 
Manager
Pool
from multiprocessing 
import cpu_count, Pool 
! 
if __name__ == '__main__': 
pool = Pool(processes=cpu_count()) 
for url in ('http://deview.kr', 
'http://beatpacking.com', 
'http://kkung.net'): 
pool.apply_async(fetch, url) 
Pool 객체는, 마치 thread pool과 같이 지정한 갯수의 프 
로세스들에 작업을 지속적으로 할당하여, 병렬처리를 손쉽 
게 할 수 있도록 지원합니다.
그렇다면 동시성은?
non blocking socket
asyncore
select / poll
asyncore 모듈이나, python 표준에 포함된 select 
등은 그래프와 같이 일반적으로 다뤄야 하는 
fd(socket)의 수가 증가할수록 비례하여 성능이 저하 
되어 효율이 극히 떨어집니다.
class Handler(asyncore.dispatcher): 
def __init__(self, host): 
pass 
! 
def handle_connect(self): 
pass 
! 
def handle_close(self): 
pass 
! 
def handle_read(self): 
pass 
! 
def handle_write(self): 
pass
connect('deview.kr', function(result, socket) { 
socket.read(function(data) { 
socket.write(data, function(result) { 
socket.close(function(result) { 
}); 
}); 
}); 
}); 
또한, 일반적으로 비동기 방식으로 I/O를 다루는 방법은 
동기적으로 I/O를 다루는 방법보다 개발의 복잡도를 높 
이고, 코드의 구조를 알아보기 어렵게 합니다.
SHOW TIME
def handle_request(s): 
try: 
s.recv(1024) 
s.send('HTTP/1.0 200 OKrn') 
s.send('Content-Type: text/plainrn') 
s.send('Content-Length: 5rn') 
s.send('rn') 
s.send('hello') 
s.close() 
except Exception, e: 
logging.exception(e)
def test(): 
s = socket.socket() 
s.setsockopt(socket.SOL_SOCKET, 
socket.SO_REUSEADDR, 1) 
s.bind(('0.0.0.0', 8000)) 
s.listen(512) 
! 
while True: 
cli, addr = s.accept() 
logging.info('accept ', addr) 
t = threading.Thread(target=handle_request, 
args=(cli, )) 
t.daemon = True 
t.start() 
클라이언트의 요청을 받으면, 지정된 응답을 내려주는 HTTP서버를 모사 
한 형태의 테스트 입니다.
Requests
 per
 second:
 
 
 
 2099.21
  
[#/sec]
 (mean)
  
! 
Time
 per
 request:
 
 
 
 
 
 
 487.803
  
[ms]
 (mean)
Requests
 per
 second:
 
 
 
 4504.64
  
[#/sec]
 (mean)
  
! 
Time
 per
 request:
 
 
 
 
 
 
 227.321
  
[ms]
 (mean)
A B 
RPS 2099 4504 214% 
TPR 487 227 214% 
gevent를 적용하기 전(A)과 gevent(moneky patch) 
를 적용한 후 (B)의 성능 비교
gevent
scheduler + 
!
scheduler + 
event loop +
scheduler + 
event loop + 
python stdlib interface
python code 
gevent 
greenlet libev 
Kernel
python code 
gevent 
greenlet libev 
thread event loop 
Kernel 
scheduler + stdlib interface api + ….
libev
현재 시스템에 
가장 적절한 event-loop 
시스템 선택
event loop
while True: 
events = wait_for_events() 
for event in events: 
handle_event(event) 
event loop란, 위 코드와 같이 event가 발생하길 기다렸다가, event가 
발생한다면 적절한 event 처리기를 실행하는 구조를 말합니다.
event?
I/O 
kernel
I/O 
kernel 
REQUEST
I/O 
BLOCK 
kernel
I/O 
kernel 
RESPONSE 
보통 I/O 요청은, 커널에 의해서 처리가 완료될때까지 
block 됩니다.
I/O 
event loop 
kernel
I/O 
event loop 
kernel 
REQUEST
I/O 
event loop 
kernel 
REQUEST 
EVENT 
RETURN
I/O 
event loop 
kernel 
EVENT
I/O 
event loop 
kernel 
callback 
RESPONSE 
그러나, event-loop을 사용한 비동기의 방식을 도입하면, I/O요청은 즉시 반 
환되어 block되지 않고, kernel에 의해서 처리가 완료되는 순간 통지 받도록 
할 수 있습니다.
Greenlet
A “greenlet”, on the other hand, is a 
still more primitive notion of micro-thread 
with no implicit scheduling; 
coroutines, in other words.
coroutine

Contenu connexe

Tendances

[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축Juhong Park
 
실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 YoungSu Son
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기Brian Hong
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 Yugo Shimizu
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들Chris Ohk
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API07.pallav
 
スマートフォン向けサービスにおけるサーバサイド設計入門
スマートフォン向けサービスにおけるサーバサイド設計入門スマートフォン向けサービスにおけるサーバサイド設計入門
スマートフォン向けサービスにおけるサーバサイド設計入門Hisashi HATAKEYAMA
 
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Jean-Michel Doudoux
 
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
[2019] 바르게, 빠르게! Reactive를 품은 Spring KafkaNHN FORWARD
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All ThingsUnityTechnologiesJapan002
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례Jemin Huh
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニックGenya Murakami
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJosé Paumard
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912Yooseok Choi
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications JavaAntoine Rey
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 

Tendances (20)

[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
[NDC 2018] Spark, Flintrock, Airflow 로 구현하는 탄력적이고 유연한 데이터 분산처리 자동화 인프라 구축
 
실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우
 
HashMapとは?
HashMapとは?HashMapとは?
HashMapとは?
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기
 
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
スマートフォン向けサービスにおけるサーバサイド設計入門
スマートフォン向けサービスにおけるサーバサイド設計入門スマートフォン向けサービスにおけるサーバサイド設計入門
スマートフォン向けサービスにおけるサーバサイド設計入門
 
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20Devoxx France 2023 - Les nouveautés de Java 19 et 20
Devoxx France 2023 - Les nouveautés de Java 19 et 20
 
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
The basics of fluentd
The basics of fluentdThe basics of fluentd
The basics of fluentd
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 

Similaire à [2D4]Python에서의 동시성_병렬성

C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)Dong Chan Shin
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumerChang Yoon Oh
 
Python으로 채팅 구현하기
Python으로 채팅 구현하기Python으로 채팅 구현하기
Python으로 채팅 구현하기Tae Young Lee
 
Netty 세미나
Netty 세미나Netty 세미나
Netty 세미나Jang Hoon
 
Concurrent programming
Concurrent programmingConcurrent programming
Concurrent programmingByeongsu Kang
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10흥배 최
 
android_thread
android_threadandroid_thread
android_threadhandfoot
 
Tensorflow service & Machine Learning
Tensorflow service & Machine LearningTensorflow service & Machine Learning
Tensorflow service & Machine LearningJEEHYUN PAIK
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&Csys4u
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)내훈 정
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍흥배 최
 
NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션흥배 최
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드KwangSeob Jeong
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기Seong Won Mun
 
쓰레드.pdf
쓰레드.pdf쓰레드.pdf
쓰레드.pdfSeokju Hong
 
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요Yongho Ha
 
H3 2011 파이썬으로 클라우드 하고 싶어요
H3 2011 파이썬으로 클라우드 하고 싶어요H3 2011 파이썬으로 클라우드 하고 싶어요
H3 2011 파이썬으로 클라우드 하고 싶어요KTH
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱jungjinwouk
 

Similaire à [2D4]Python에서의 동시성_병렬성 (20)

C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumer
 
Python으로 채팅 구현하기
Python으로 채팅 구현하기Python으로 채팅 구현하기
Python으로 채팅 구현하기
 
Netty 세미나
Netty 세미나Netty 세미나
Netty 세미나
 
Concurrent programming
Concurrent programmingConcurrent programming
Concurrent programming
 
Gcd ppt
Gcd pptGcd ppt
Gcd ppt
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
android_thread
android_threadandroid_thread
android_thread
 
Tensorflow service & Machine Learning
Tensorflow service & Machine LearningTensorflow service & Machine Learning
Tensorflow service & Machine Learning
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&C
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍
 
NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기
 
쓰레드.pdf
쓰레드.pdf쓰레드.pdf
쓰레드.pdf
 
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
 
H3 2011 파이썬으로 클라우드 하고 싶어요
H3 2011 파이썬으로 클라우드 하고 싶어요H3 2011 파이썬으로 클라우드 하고 싶어요
H3 2011 파이썬으로 클라우드 하고 싶어요
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱
 

Plus de NAVER D2

[211] 인공지능이 인공지능 챗봇을 만든다
[211] 인공지능이 인공지능 챗봇을 만든다[211] 인공지능이 인공지능 챗봇을 만든다
[211] 인공지능이 인공지능 챗봇을 만든다NAVER D2
 
[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...
[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...
[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...NAVER D2
 
[215] Druid로 쉽고 빠르게 데이터 분석하기
[215] Druid로 쉽고 빠르게 데이터 분석하기[215] Druid로 쉽고 빠르게 데이터 분석하기
[215] Druid로 쉽고 빠르게 데이터 분석하기NAVER D2
 
[245]Papago Internals: 모델분석과 응용기술 개발
[245]Papago Internals: 모델분석과 응용기술 개발[245]Papago Internals: 모델분석과 응용기술 개발
[245]Papago Internals: 모델분석과 응용기술 개발NAVER D2
 
[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈
[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈
[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈NAVER D2
 
[235]Wikipedia-scale Q&A
[235]Wikipedia-scale Q&A[235]Wikipedia-scale Q&A
[235]Wikipedia-scale Q&ANAVER D2
 
[244]로봇이 현실 세계에 대해 학습하도록 만들기
[244]로봇이 현실 세계에 대해 학습하도록 만들기[244]로봇이 현실 세계에 대해 학습하도록 만들기
[244]로봇이 현실 세계에 대해 학습하도록 만들기NAVER D2
 
[243] Deep Learning to help student’s Deep Learning
[243] Deep Learning to help student’s Deep Learning[243] Deep Learning to help student’s Deep Learning
[243] Deep Learning to help student’s Deep LearningNAVER D2
 
[234]Fast & Accurate Data Annotation Pipeline for AI applications
[234]Fast & Accurate Data Annotation Pipeline for AI applications[234]Fast & Accurate Data Annotation Pipeline for AI applications
[234]Fast & Accurate Data Annotation Pipeline for AI applicationsNAVER D2
 
Old version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing
Old version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load BalancingOld version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing
Old version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load BalancingNAVER D2
 
[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지
[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지
[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지NAVER D2
 
[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기
[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기
[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기NAVER D2
 
[224]네이버 검색과 개인화
[224]네이버 검색과 개인화[224]네이버 검색과 개인화
[224]네이버 검색과 개인화NAVER D2
 
[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)
[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)
[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)NAVER D2
 
[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기
[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기
[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기NAVER D2
 
[213] Fashion Visual Search
[213] Fashion Visual Search[213] Fashion Visual Search
[213] Fashion Visual SearchNAVER D2
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화NAVER D2
 
[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지
[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지
[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지NAVER D2
 
[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터
[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터
[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터NAVER D2
 
[223]기계독해 QA: 검색인가, NLP인가?
[223]기계독해 QA: 검색인가, NLP인가?[223]기계독해 QA: 검색인가, NLP인가?
[223]기계독해 QA: 검색인가, NLP인가?NAVER D2
 

Plus de NAVER D2 (20)

[211] 인공지능이 인공지능 챗봇을 만든다
[211] 인공지능이 인공지능 챗봇을 만든다[211] 인공지능이 인공지능 챗봇을 만든다
[211] 인공지능이 인공지능 챗봇을 만든다
 
[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...
[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...
[233] 대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing: Maglev Hashing Scheduler i...
 
[215] Druid로 쉽고 빠르게 데이터 분석하기
[215] Druid로 쉽고 빠르게 데이터 분석하기[215] Druid로 쉽고 빠르게 데이터 분석하기
[215] Druid로 쉽고 빠르게 데이터 분석하기
 
[245]Papago Internals: 모델분석과 응용기술 개발
[245]Papago Internals: 모델분석과 응용기술 개발[245]Papago Internals: 모델분석과 응용기술 개발
[245]Papago Internals: 모델분석과 응용기술 개발
 
[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈
[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈
[236] 스트림 저장소 최적화 이야기: 아파치 드루이드로부터 얻은 교훈
 
[235]Wikipedia-scale Q&A
[235]Wikipedia-scale Q&A[235]Wikipedia-scale Q&A
[235]Wikipedia-scale Q&A
 
[244]로봇이 현실 세계에 대해 학습하도록 만들기
[244]로봇이 현실 세계에 대해 학습하도록 만들기[244]로봇이 현실 세계에 대해 학습하도록 만들기
[244]로봇이 현실 세계에 대해 학습하도록 만들기
 
[243] Deep Learning to help student’s Deep Learning
[243] Deep Learning to help student’s Deep Learning[243] Deep Learning to help student’s Deep Learning
[243] Deep Learning to help student’s Deep Learning
 
[234]Fast & Accurate Data Annotation Pipeline for AI applications
[234]Fast & Accurate Data Annotation Pipeline for AI applications[234]Fast & Accurate Data Annotation Pipeline for AI applications
[234]Fast & Accurate Data Annotation Pipeline for AI applications
 
Old version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing
Old version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load BalancingOld version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing
Old version: [233]대형 컨테이너 클러스터에서의 고가용성 Network Load Balancing
 
[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지
[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지
[226]NAVER 광고 deep click prediction: 모델링부터 서빙까지
 
[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기
[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기
[225]NSML: 머신러닝 플랫폼 서비스하기 & 모델 튜닝 자동화하기
 
[224]네이버 검색과 개인화
[224]네이버 검색과 개인화[224]네이버 검색과 개인화
[224]네이버 검색과 개인화
 
[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)
[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)
[216]Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템)
 
[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기
[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기
[214] Ai Serving Platform: 하루 수 억 건의 인퍼런스를 처리하기 위한 고군분투기
 
[213] Fashion Visual Search
[213] Fashion Visual Search[213] Fashion Visual Search
[213] Fashion Visual Search
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화
 
[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지
[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지
[242]컴퓨터 비전을 이용한 실내 지도 자동 업데이트 방법: 딥러닝을 통한 POI 변화 탐지
 
[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터
[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터
[212]C3, 데이터 처리에서 서빙까지 가능한 하둡 클러스터
 
[223]기계독해 QA: 검색인가, NLP인가?
[223]기계독해 QA: 검색인가, NLP인가?[223]기계독해 QA: 검색인가, NLP인가?
[223]기계독해 QA: 검색인가, NLP인가?
 

[2D4]Python에서의 동시성_병렬성

  • 1. Python 동시성/병렬성 DEVIEW 2014 정민영 @ 비트패킹컴퍼니
  • 2. 발표자 • 정민영 • 미투데이 / 비트패킹컴퍼니 • 07년 Nginx를 만난 후 비동기 덕후 • kkung@beatpacking.com
  • 4.
  • 6. def calc(): return max([random() for x in xrange(20000000)]) ! if __name__ == '__main__': print(calc()) print(calc()) 4.418s
  • 7. if __name__ == '__main__': threads = [] for i in xrange(2): threads.append(threading.Thread(target=calc)) threads[-1].start() for t in threads: t.join() 7.683s
  • 8.
  • 10. 왜 thread가 더 느리지?
  • 14. Thread 1 Thread 2 Thread 3
  • 15. Thread 1 Thread 2 Thread 3 3개의 Python thread가 수행되고 있는 상태에서, Thread 1이 수행되고 있는 상황의 예를 보겠습니다.
  • 16. Thread 1 Thread 2 Thread 3 I/O
  • 17. Thread 1 Thread 2 Thread 3 I/O release GIL
  • 18. Thread 1 Thread 2 Thread 3 I/O release GIL acquire GIL
  • 19. Thread 1 Thread 2 Thread 3 I/O release GIL Context Switch acquire GIL Python은, I/O(/System call)이 발생하게 되면, thread는 GIL을 해제하게 되고, 다른 GIL을 획득 하는 thread로 제어권이 넘어갑니다.
  • 20. Thread 1 Thread 2 Thread 3 I/O release GIL Context Switch acquire GIL Python은, I/O와 같은 경우 처럼 Python 객체를 건드리지 않고, 계속 수행할 필요가 있을 경우 Py_BEGIN_ALLOW_THREADS 를 통해서, 계속 thread를 수행하게 할 수 있습니다.
  • 21. 또한, system call뿐만 아니라, Python byte code 상에서 100개가 실행될 때마다도 마찬가지로 GIL을 해제함으로써, 다른 thread로 제어권을 넘기게 됩니다. Thread 1 Thread 2 Thread 3 I/O 100 tick release GIL C/S acquire GIL
  • 22. Python은 사실상 Single Thread 따라서, Python은 threading 모듈을 통해서 여러 thread 를 생성할 수 있음에도 불구하고, 사실상 GIL에 의해서 예 외적인 경우를 제외하고, 한 시점에는 하나의 thread만 작 동하는 것 처럼 보이게 됩니다.
  • 24. Thread 1 Thread 2 Thread 3 I/O I/O
  • 25. Thread 1 Thread 2 Thread 3 I/O I/O
  • 26. Thread 1 Thread 2 Thread 3 I/O I/O C/S ? System call에 의해서 GIL을 획득하지 못한 thread가 계속 수행되는 경우에도, system call이 종료되고 python 코드를 수행하기 위해서는 GIL을 획득해야하기 때문에, 원하는 시점에 thread가 제어권을 다시 획 득하는 보장이 없습니다.
  • 29. 어떤 thread로 넘어갈지는 사실상 랜덤 Python은 별도의 thread 스케쥴링 없이, 시스템이 제공하는 threading library의 lock mechanism에 의해서 문맥이 전환됩니다.
  • 30. 그럼, GIL은 무조건 나쁜가요?
  • 32. (상대적으로) 단순한 구현 적은 버그와 용이한 구현
  • 33. single thread 성능에 우위 Python은 memory 관리를 reference counting의 방법으로 하는데, GIL에 대비되는 fine-grained lock방법을 사용할 경우 모든 객체의 접 근마다 lock 으로 관리해야 하므로 그 overhead가 매우 큽니다.
  • 35.
  • 36. 더 많은 일을 빠르게 처리하려면?
  • 37. 일?
  • 39. 수행시간에 CPU가 더 영향이 큰 작업
  • 42. 수행시간에 I/O가 더 영향이 큰 작업
  • 45. 이런 일을 더 많이, 더 빠르게
  • 55. 그럼 python은 병렬성은 물건너 갔나요?
  • 56. “(…) If you want your application to make better use of the computational resources of multi-core machines, you are advised to use multiprocessing. (…)” https://docs.python.org/2/library/threading.html
  • 58.
  • 59. Fork
  • 60. if __name__ == '__main__': processes = [] for i in xrange(2): processes.append(multiprocessing.Process(target=calc)) processes[-1].start() p.join() 2.431s for p in processes:
  • 61. multiprocessing 모듈은, fork를 통해서 동시에 여러 프로세스에 원하는 작업을 실행할 수 있도록 도와주는 모듈입니다. 앞서 예제 코드를 실행할 경우, main process를 포함해서 추가로 2개의 프로세스가 작동하 여 병렬화 되는 모습을 확인할 수 있습니다.
  • 63. Lock
  • 64. Shared Memory / Manager
  • 65. Pool
  • 66. from multiprocessing import cpu_count, Pool ! if __name__ == '__main__': pool = Pool(processes=cpu_count()) for url in ('http://deview.kr', 'http://beatpacking.com', 'http://kkung.net'): pool.apply_async(fetch, url) Pool 객체는, 마치 thread pool과 같이 지정한 갯수의 프 로세스들에 작업을 지속적으로 할당하여, 병렬처리를 손쉽 게 할 수 있도록 지원합니다.
  • 71.
  • 72. asyncore 모듈이나, python 표준에 포함된 select 등은 그래프와 같이 일반적으로 다뤄야 하는 fd(socket)의 수가 증가할수록 비례하여 성능이 저하 되어 효율이 극히 떨어집니다.
  • 73.
  • 74. class Handler(asyncore.dispatcher): def __init__(self, host): pass ! def handle_connect(self): pass ! def handle_close(self): pass ! def handle_read(self): pass ! def handle_write(self): pass
  • 75. connect('deview.kr', function(result, socket) { socket.read(function(data) { socket.write(data, function(result) { socket.close(function(result) { }); }); }); }); 또한, 일반적으로 비동기 방식으로 I/O를 다루는 방법은 동기적으로 I/O를 다루는 방법보다 개발의 복잡도를 높 이고, 코드의 구조를 알아보기 어렵게 합니다.
  • 76.
  • 78. def handle_request(s): try: s.recv(1024) s.send('HTTP/1.0 200 OKrn') s.send('Content-Type: text/plainrn') s.send('Content-Length: 5rn') s.send('rn') s.send('hello') s.close() except Exception, e: logging.exception(e)
  • 79. def test(): s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('0.0.0.0', 8000)) s.listen(512) ! while True: cli, addr = s.accept() logging.info('accept ', addr) t = threading.Thread(target=handle_request, args=(cli, )) t.daemon = True t.start() 클라이언트의 요청을 받으면, 지정된 응답을 내려주는 HTTP서버를 모사 한 형태의 테스트 입니다.
  • 81.  per
  • 83.  
  • 84.  
  • 85.  
  • 90.  per
  • 92.  
  • 93.  
  • 94.  
  • 95.  
  • 96.  
  • 97.  
  • 102.  per
  • 104.  
  • 105.  
  • 106.  
  • 111.  per
  • 113.  
  • 114.  
  • 115.  
  • 116.  
  • 117.  
  • 118.  
  • 122. A B RPS 2099 4504 214% TPR 487 227 214% gevent를 적용하기 전(A)과 gevent(moneky patch) 를 적용한 후 (B)의 성능 비교
  • 123.
  • 124. gevent
  • 126. scheduler + event loop +
  • 127. scheduler + event loop + python stdlib interface
  • 128. python code gevent greenlet libev Kernel
  • 129. python code gevent greenlet libev thread event loop Kernel scheduler + stdlib interface api + ….
  • 130. libev
  • 131. 현재 시스템에 가장 적절한 event-loop 시스템 선택
  • 133. while True: events = wait_for_events() for event in events: handle_event(event) event loop란, 위 코드와 같이 event가 발생하길 기다렸다가, event가 발생한다면 적절한 event 처리기를 실행하는 구조를 말합니다.
  • 134. event?
  • 138. I/O kernel RESPONSE 보통 I/O 요청은, 커널에 의해서 처리가 완료될때까지 block 됩니다.
  • 139. I/O event loop kernel
  • 140. I/O event loop kernel REQUEST
  • 141. I/O event loop kernel REQUEST EVENT RETURN
  • 142. I/O event loop kernel EVENT
  • 143. I/O event loop kernel callback RESPONSE 그러나, event-loop을 사용한 비동기의 방식을 도입하면, I/O요청은 즉시 반 환되어 block되지 않고, kernel에 의해서 처리가 완료되는 순간 통지 받도록 할 수 있습니다.
  • 145. A “greenlet”, on the other hand, is a still more primitive notion of micro-thread with no implicit scheduling; coroutines, in other words.
  • 148. def hello(): while True: name = (yield) print 'Hello %s' % name ! c = hello() c.next() c.send('kkung') c.send('Deview 2014') ! Hello kkung Hello Deview 2014 python의 generator를 이용한 coroutine 예제 입니다. hello() 함수는 무한 루프를 도는 함수임에도 불구하고, 예제와 같이 출력되는 모습을 볼 수 있습니다.
  • 149. def hello(): while True: name = (yield) print 'Hello %s' % name ! c = hello() c.next() c.send('kkung') c.send('Deview 2014') ! Hello kkung Hello Deview 2014 hello 함수는 내부적으로 무한 루프를 돌도록 되어 있으나 yield를 포함하고 있어 generator 함수로 처리되며, c.next()에 의해서 진입합니다.
  • 150. def hello(): while True: name = (yield) print 'Hello %s' % name ! c = hello() c.next() c.send('kkung') c.send('Deview 2014') ! Hello kkung Hello Deview 2014 yield에 의해 문맥은 다시 hello() 함수 바깥으로 전환되고, c.send(‘kkung’) 에 의해서 ‘kkung’이 전달됨과 동시에, 문맥이 hello 함수로 전환됩니다.
  • 151. def hello(): while True: name = (yield) print 'Hello %s' % name ! c = hello() c.next() c.send('kkung') c.send('Deview 2014') ! Hello kkung Hello Deview 2014 hello 함수는, 문맥이 전환됨에 따라(재진입) print문을 실행하게 됩니다.
  • 154. MAIN THREAD Coroutine Coroutine Coroutine Coroutine greenlet은, 특정 python thread에 귀속되며 실제 thread보다 훨씬 가벼워 많은 수의 greenlet을 저렴하게 생성할 수 있습니다.
  • 155. MAIN THREAD Coroutine Coroutine Coroutine Coroutine
  • 156. MAIN THREAD Coroutine Coroutine Coroutine Coroutine
  • 157. MAIN THREAD Coroutine Coroutine Coroutine Coroutine
  • 158. MAIN THREAD Coroutine Coroutine Coroutine Coroutine 앞서 설명했던 바와 같이 GIL은 시스템의 threading library의 lock mechanism에 의존적이기 때문에 문맥 전환이 암시적입니다. 그러나 greenlet은 그림과 같이 명시적으로 문맥을 전환시킵니다.
  • 160. 너무 많은 일을 하면 X greenlet은, 앞서 설명한바와 같이 특정 thread에서 귀속되며 그 thread단위로 스케쥴링 됩니다. 이는 특정 greenlet이 CPU를 오 래 점유하면 할 수록, 같은 thread에 있는 다른 greenlet들은 idle 상태를 유지한다는 말과 같습니다.
  • 161. Sync-like API (NO CALLBACK!) gevent의 장점중 한가지는, Python에 존재하는 표준 library의 인 터페이스를 그대로 변화 없이 사용해도, 비동기적인 처리 효과를 제 공해 준다는 점입니다.
  • 163. connect('deview.kr', function(result, socket) { socket.read(function(data) { socket.write(data, function(result) { socket.close(function(result) { }); }); }); }); 예를들어, 특정 언어에서는 비동기 처리를 위해서 callback을 연쇄 적으로 제공하는 방법(CPS)외에는 선택지가 없는 경우도 있지만….
  • 164. s.connect('deview.kr') data = s.read() s.write(data) s.close() gevent를 사용한다면, Python에서는 이렇게 직관적으로도 비동기 처리를 할 수 있습니다. (특정 언어 비하의 의도는 없습니다^^;)
  • 165. connect('deview.kr', function(result, socket) { socket.read(function(data) { socket.write(data, function(result) { socket.close(function(result) { }); }); }); }); s.connect('deview.kr') data = s.read() s.write(data) s.close()
  • 166. def recv(self, *args): while True: try: return sock.recv(*args) except error as ex: if ex.args[0] != EWOULDBLOCK: raise self._wait(self._read_event)
  • 167. def recv(self, *args): while True: try: return sock.recv(*args) except error as ex: if ex.args[0] != EWOULDBLOCK: raise self._wait(self._read_event)
  • 168. def recv(self, *args): while True: try: return sock.recv(*args) except error as ex: if ex.args[0] != EWOULDBLOCK: raise self._wait(self._read_event) 이것이 가능한 이유는, gevent는 내부적으로 python library의 인터페이스를 그대로 구현하면서, 각 API를 모두 greenlet에서 수행하기 때문입니다. Non block socket을 이용해서, 요청한 순간 바로 처리할 수 없다면 event-loop에서 처리 가능해질때 greenlet을 깨우도록 기다립니다.
  • 171. import asyncio ! @asyncio.coroutine def compute(x, y): print(Compute %s + %s ... % (x, y)) yield from asyncio.sleep(1.0) return x + y ! @asyncio.coroutine def print_sum(x, y): result = yield from compute(x, y) print(%s + %s = %s % (x, y, result)) ! loop = asyncio.get_event_loop() loop.run_until_complete(print_sum(1, 2)) loop.close() Python 3.4 이상부터는, AsyncIO 라이브러리를 이용할 수도 있습니다. 이 라이브러리 는, python 3.3에서 도입된 yield from 문법을 이용해서 coroutine을 구현하여 좀 더 pythonic한 방법으로 비동기 처리를 제공합니다.
  • 172. import asyncio ! @asyncio.coroutine def compute(x, y): print(Compute %s + %s ... % (x, y)) yield from asyncio.sleep(1.0) return x + y ! @asyncio.coroutine def print_sum(x, y): result = yield from compute(x, y) print(%s + %s = %s % (x, y, result)) ! loop = asyncio.get_event_loop() loop.run_until_complete(print_sum(1, 2)) loop.close()
  • 173. import asyncio ! @asyncio.coroutine def compute(x, y): print(Compute %s + %s ... % (x, y)) yield from asyncio.sleep(1.0) return x + y ! @asyncio.coroutine def print_sum(x, y): result = yield from compute(x, y) print(%s + %s = %s % (x, y, result)) ! loop = asyncio.get_event_loop() loop.run_until_complete(print_sum(1, 2)) loop.close()
  • 174. import asyncio ! @asyncio.coroutine def compute(x, y): print(Compute %s + %s ... % (x, y)) yield from asyncio.sleep(1.0) return x + y ! @asyncio.coroutine def print_sum(x, y): result = yield from compute(x, y) print(%s + %s = %s % (x, y, result)) ! loop = asyncio.get_event_loop() loop.run_until_complete(print_sum(1, 2)) loop.close()
  • 175. 앞서, coroutine은 진입점이 여러개인 함수다 라는 표현을 사용하였는데, 위 코드에서 보는 바와 같이 print_sum, compute, asyncio.sleep 이 각 호출되면서도 종료시에 yield from의 다음 줄이 수행되는 모습을 볼 수 있습니다.
  • 178. from gevent import monkey monkey.patch_all() monkey patch는, python 표준 라이브러리들 중 IO에 관계 있는 주요 라이브러리들 을, gevent의 그것으로 대체시킵니다. 따라서, monkey patch후에는 기존의 python 에서 IO를 다루던 방법 그래도 수행하여도, gevent에 의해서 비동기 처리로 전환됩니다.
  • 179. from gevent.pool import Pool pool = Pool(1024)
  • 180. def upload_to_s3(file_name): bucket.new_key(file_name) .set_contents_from_fi lename(file_name)
  • 181. for file_name in files: pool.spawn(upload_to_s3, file_name) gevent.wait()
  • 183. recap
  • 184. CPU가 많이 필요한 일은 multiprocessing
  • 185. I/O가 많이 필요한 일은 gevent/AsyncIO