2

우리는 전자 상거래 응용 프로그램을 만들고 싶습니다. 팀은 Python 개발자이지만 Python 웹 프레임 워크 (Django/Flask ...)를 사용하지 않습니다. 우리는 토네이도가 단순함으로 우수하다는 것을 알았 기 때문에 큰 비율.ThreadPoolExecutor가 단일 스레드 응용 프로그램의 효율성을 높일 수 있습니까?

그러나 문제는 토네이도가 단일 스레드이며 응용 프로그램이 해싱 (로그인) 및 이미지 처리 (축소판 생성)를 사용한다는 것입니다. ThreadPoolExecutor은이 예제처럼 Apache와 같은 멀티 스레딩 서버 역할을 할 수 있습니까?

from concurrent.futures import ThreadPoolExecutor 
from tornado import gen 
from tornado.process import cpu_count 
import bcrypt 


pool = ThreadPoolExecutor(cpu_count()) 

@gen.coroutine 
def create_user(name, password): 
    hashed_pw = yield pool.submit(bcrypt.hashpw, password, bcrypt.gensalt()) 
    yield save_user(name, hashed_pw) 

@gen.coroutine 
def login(name, password): 
    user = yield load_user(name) 
    match = yield pool.submit(bcrypt.checkpw, password, user.hashed_pw) 
    if not match: 
     raise IncorrectPasswordError() 

따라서 토네이도는 해싱 작업을 다른 스레드로 보내 자신을 해방하고 다른 요청을받을 수있게합니다. 이 접근 방식이 효과가 있습니까?

NB :로드 밸런서가 포함 된 솔루션도 있지만 팀은 현재이 솔루션을 추구하고 싶지 않습니다.

답변

2

예, ThreadPoolExecutor이 여기에서 잘 작동합니다. 모두 hashpwcheckpw 자신의 작업의 CPU-무거운 부품 동안 GIL을 해제 나타납니다 다른 CPU로 들어오는 요청을 처리하는 동안, 당신은 하나 개의 CPU에 떨어져 작동 농장을 할 수 있습니다 의미

bcrypt_hashpw(PyObject *self, PyObject *args, PyObject *kw_args) 
{ 
    ... 
    Py_BEGIN_ALLOW_THREADS; 
    ret = pybc_bcrypt(password_copy, salt_copy, hashed, sizeof(hashed)); 
    Py_END_ALLOW_THREADS; 
    ... 

합니다.

순수한 Python을 실행하는 다른 CPU 바인딩 작업 (GIL이 출시되지 않음을 의미)을 수행해야하는 경우 성능이 저하되지 않도록하려면 ProcessPoolExecutor을 사용해야합니다 .

+0

그래서 '베개'도 똑같습니까? (데이터베이스) – Abdelouahab

+1

@Abdelouahab 'pillow'소스를 간략하게 살펴보면 C 확장이 여러 위치에서 GIL을 해제한다는 것을 알 수 있습니다. 따라서 적어도 경우에 따라서는'ThreadPoolExecutor'와 잘 동작합니다. 나는 모든 작업이 그것을 릴리스한다고 확실히 말할 수 없다. – dano

+0

아, 그래서 이것은 엄지 손가락의 규칙입니다 : GIL을 풀어 준다면, 나는 그것을 최적화 할 수 있습니다;) 고맙습니다. :) – Abdelouahab

관련 문제