如何将子线程变量传递至主线程并实现自动重置?
问题
能否将子线程thread1中task函数内的变量a、b传递至主线程thread0的while循环中?要求主线程使用一次这些变量后,自动将其重置为0。尝试将变量设为全局变量但未生效,这种场景下能否对变量使用Lock?
尝试代码
# example of running a function in another thread from threading import Thread, Lock import time global a global b # setting some initial variables (needed?) a = 0 b = 0 # a custom function that will run commands for new thread ("thread1") def task(): while True: global a global b #lets reset the values to ensure they are 0 a = 0 b = 0 print "This is the TASK function.\n" a = int(raw_input("Enter number: ")) b = int(a * 5.6) print "I received: ", a print "I calculated: ", b # create & run a new thread ("thread1") thread = Thread(target=task) thread.daemon = True thread.start() while True: print "-------------------------------" print "HERE I'm running the MAIN thread (thread0)." print "DEGREES received from TASK function: ", a print "COUNTS received from TASK function: ", b time.sleep(1)
预期输出
python ./thread2.py This is the TASK function. Enter number: ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 5 (**** note this is the number entered by the user****) I received: 5 I calculated: 28 This is the TASK function. ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 5 COUNTS received from TASK function: 28 ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 ------------------------------- Enter number: HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 8 (**** note this is the number entered by the user****) I received: 8 I calculated: 45 This is the TASK function. Enter number: ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 8 COUNTS received from TASK function: 45 ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 ------------------------------- HERE I'm running the MAIN thread (thread0). DEGREES received from TASK function: 0 COUNTS received from TASK function: 0 -------------------------------
解答
问题根源
你之前的代码里,子线程task的while循环每次启动都会立刻把a、b重置为0,而且主线程和子线程读写全局变量时没有同步,导致主线程要么读不到新值,要么刚读到就被子线程重置,所以全局变量看似“没生效”。
关于Lock的使用
这种场景必须用Lock,多线程共享变量时,读写操作需要保证原子性,否则会出现竞态条件(比如主线程读取到一半,子线程修改了变量值)。
修改后的代码
from threading import Thread, Lock import time # 初始化全局变量和锁 a = 0 b = 0 lock = Lock() def task(): global a, b while True: print "This is the TASK function.\n" # 获取用户输入并计算 input_num = int(raw_input("Enter number: ")) calc_num = int(input_num * 5.6) print "I received: ", input_num print "I calculated: ", calc_num # 加锁更新全局变量 with lock: a = input_num b = calc_num # 子线程不需要主动重置,交给主线程处理 # 创建并启动子线程 thread = Thread(target=task) thread.daemon = True thread.start() while True: print "-------------------------------" print "HERE I'm running the MAIN thread (thread0)." # 加锁读取并重置变量 with lock: current_a = a current_b = b # 读取后立即重置为0 a = 0 b = 0 print "DEGREES received from TASK function: ", current_a print "COUNTS received from TASK function: ", current_b time.sleep(1)
代码说明
- Lock同步:用
with lock:上下文管理器自动处理锁的获取和释放,保证读写全局变量时只有一个线程在操作,避免竞态。 - 重置逻辑转移:子线程不再主动重置
a、b,而是在主线程读取完成后立即重置,确保主线程能读取到子线程设置的新值一次。 - 阻塞处理:子线程的
raw_input会阻塞,直到用户输入,避免无意义的循环。
这样修改后,就能实现你想要的效果:主线程每次读取到子线程设置的新值,输出后下一次循环就会输出0,直到子线程再次设置新值。
内容的提问来源于stack exchange,提问作者luke
相关产品推荐
相关产品推荐

