여러 스레드에서 동일한 변수를 사용해 보았지만 변수 값이 스레드 전체에서 일관되게 업데이트되지 않았습니다. 예를 들어 스레드 1이 변수를 1로 업데이트하면 스레드 2는 이 변경 사항을 인식하지 못하고 대신 이전 값을 봅니다.
다음은 문제를 설명하는 간단한 코드 예제입니다. 사용자가 "a" 키를 누르면 "query" 변수가 업데이트되어 다음과 같이 표시되어야 합니다.
그러나 내가 얻는 실제 결과는 다음과 같습니다.
이런 일이 발생하는 이유와 해결 방법을 이해하도록 도와주실 수 있나요?
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!