본문 바로가기
파이썬

파이썬 플라스크에서 전역 변수는 스레드로부터 안전합니까? 요청간에 데이터를 공유하려면 어떻게합니까?

by º기록 2020. 11. 17.
반응형

내 앱에서 공통 객체의 상태는 요청을 통해 변경되며 응답은 상태에 따라 다릅니다.

class SomeObj():
    def __init__(self, param):
        self.param = param
    def query(self):
        self.param += 1
        return self.param

global_obj = SomeObj(0)

@app.route('/')
def home():
    flash(global_obj.query())
    render_template('index.html')

내 개발 서버에서 이것을 실행하면 1, 2, 3 등이 나올 것으로 예상됩니다. 100 개의 서로 다른 클라이언트에서 동시에 요청을하면 문제가 발생할 수 있습니까? 예상되는 결과는 100 개의 서로 다른 클라이언트가 각각 1에서 100까지의 고유 한 숫자를 보는 것입니다. 또는 다음과 같은 일이 발생합니다.

클라이언트가 두 개뿐이므로 예상 결과는 2와 3이 아니라 1과 2였습니다. 숫자를 건너 뛰었습니다.

애플리케이션을 확장 할 때 실제로 이런 일이 발생합니까? 전역 변수에 대한 대안은 무엇입니까?

 

해결 방법

 

이러한 종류의 데이터를 보유하기 위해 전역 변수를 사용할 수 없습니다. 스레드로부터 안전하지 않을뿐만 아니라 프로세스 도 안전하지 않으며 프로덕션 환경의 WSGI 서버는 여러 프로세스를 생성합니다. 요청을 처리하기 위해 스레드를 사용하는 경우 계산이 잘못되었을뿐만 아니라 요청을 처리 한 프로세스에 따라 달라질 수 있습니다.


개발 서버는 단일 스레드 및 프로세스에서 실행될 수 있습니다. 각 요청이 동 기적으로 처리되기 때문에 설명하는 동작을 볼 수 없습니다. 스레드 또는 프로세스를 활성화하면 볼 수 있습니다. app.run (threaded = True) 또는 app.run (processes = 10) . (1.0에서는 서버가 기본적으로 스레드됩니다.)

일부 WSGI 서버는 gevent 또는 다른 비동기 작업자를 지원할 수 있습니다. 전역 변수는 여전히 대부분의 경쟁 조건에 대한 보호가 없기 때문에 스레드로부터 안전하지 않습니다. 한 작업자가 값을 얻고, 양보하고, 다른 작업자가 값을 수정하고, 양보 한 다음 첫 번째 작업자도 값을 수정하는 시나리오를 가질 수 있습니다.


 

참조 페이지 https://stackoverflow.com/questions/32815451

 

 

반응형

댓글