>백엔드 개발 >파이썬 튜토리얼 >한 스레드에서 공유 변수에 대한 변경 사항이 Python의 다른 스레드에 보이지 않는 이유는 무엇입니까?

한 스레드에서 공유 변수에 대한 변경 사항이 Python의 다른 스레드에 보이지 않는 이유는 무엇입니까?

WBOY
WBOY앞으로
2024-02-06 11:03:111196검색

为什么 Python 中一个线程对共享变量所做的更改对其他线程不可见?

질문 내용

여러 스레드에서 동일한 변수를 사용해 보았지만 변수 값이 스레드 전체에서 일관되게 업데이트되지 않았습니다. 예를 들어 스레드 1이 변수를 1로 업데이트하면 스레드 2는 이 변경 사항을 인식하지 못하고 대신 이전 값을 봅니다.

다음은 문제를 설명하는 간단한 코드 예제입니다. 사용자가 "a" 키를 누르면 "query" 변수가 업데이트되어 다음과 같이 표시되어야 합니다.

  1. 쿼리 1: a
  2. 쿼리: a

그러나 내가 얻는 실제 결과는 다음과 같습니다.

  1. 쿼리 1: a

이런 일이 발생하는 이유와 해결 방법을 이해하도록 도와주실 수 있나요?

import getch
import threading

QUERY = ""
EXIT_THREAD = False
def input_thread():
    global EXIT_THREAD
    last_query = ""
    while not EXIT_THREAD:
        if last_query != QUERY:
            last_query = QUERY
            print(f"Query: {QUERY}")

thread = threading.Thread(target=input_thread)
thread.start()
while True:
    char = getch.getch()
    if char == "\n":
        break
    elif char == "\x7f":
        QUERY = QUERY[:-1]
    else:
        QUERY += char
    print(f"Query1: {QUERY}")
# kill input thread
EXIT_THREAD = True
thread.join()

정답


질문은 getch 模块编码很差。当它阻塞等待输入时,它不会释放gil(全局解释器锁),因此您的其他线程不允许运行。与锁同步并没有多大帮助; gil 已保护对 query액세스 입니다.

문제는 모든 변경query 后,您都会返回到 getch,这会锁定 gil。当 getch 返回时,已经过去了足够的时间,gil 立即被移交,另一个线程检查更改,看到最后的更改并报告它,主线程最终得到返回控制权,但通常在 getch 再次锁定它之前没有做足够的事情来导致另一次 gil 切换,并且另一个线程永远没有机会运行并看到更改,直到 getch이 다음에 다시 돌아온다는 것입니다. 이는 Python 버전에 따라 다를 수 있지만(Gil을 확인하는 규칙은 수시로 변경됨) 항상 불안정합니다.

올바른 해결책은 getch 模块在进行阻塞调用之前在内部释放 gil,但如果做不到这一点,您可以通过在每个 getch 之前故意以 gil 释放方式阻塞来给其他线程一些运行时间调用时,通过导入 time 모듈에 절전 모드를 추가하여 다른 스레드가 최신 변경 사항을 볼 수 있는 시간을 주는 것입니다.

으아아아

이것은 예상한 동작을 얻습니다. 기술적으로는 다른 스레드가 관련된 경우 경쟁 조건이 발생할 수 있지만 이와 같은 두 스레드의 경우 꽤 안정적입니다.

위 내용은 한 스레드에서 공유 변수에 대한 변경 사항이 Python의 다른 스레드에 보이지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제