为什么在python中使用线程时不增加全局变量?

为什么在python中使用线程时不增加全局变量?,python,multithreading,Python,Multithreading,对于我的代码,pytest_status['finished']变量以非常有趣的方式递增。有时我会看到“2”或“3”(我希望每次运行测试函数调用都会相应递增): 等等。我特意把它从锁里拿出来,我的代码: import subprocess from multiprocessing import Pool, Lock pytest_status = { 'finished' : 0, 'total' : 0 } print_lock = Lock() def run_t

对于我的代码,pytest_status['finished']变量以非常有趣的方式递增。有时我会看到“2”或“3”(我希望每次运行测试函数调用都会相应递增):

等等。我特意把它从锁里拿出来,我的代码:

import subprocess
from multiprocessing import Pool, Lock

pytest_status = {
    'finished' : 0,
    'total'    : 0
}

print_lock = Lock()

def run_test(test):
    status = subprocess.call(...)

    global pytest_status
    pytest_status['finished'] += 1

    print_lock.acquire()
    print 'test ' + str(pytest_status['finished']) + '/' + str(pytest_status['total']) + ': ' + ('success' if status == 0 else 'failure')    
    print_lock.release()

def main():
    params = [...]

    global pytest_status    
    pytest_status['total'] = len(params)

    print 'will perform ' + str(pytest_status['total']) + ' tests'

    pool = Pool(30)
    pool.map(run_test, params)
    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

你没有使用线程。您正在使用进程。根据定义,它们具有所有数据的单独副本。只有当同一进程运行多个作业时,才会得到2或3个线程。

您没有使用线程。您正在使用进程。根据定义,它们具有所有数据的单独副本。只有当同一进程运行多个作业时,才会得到2或3个作业。

如果要在进程之间传输数据,可以使用管道或查询。

如果要在进程之间传输数据,可以使用管道或查询。

。。上帝是否有办法在它们之间共享变量?有关如何使用
Value
Array
的示例,请参阅。请记住:如果您有一个全局变量“a”,并在函数中使用它,则后一个变量只是全局变量的副本。如果你真的想改变全局变量的内容,你必须写一次“全局a”!这不应该适用于您的代码,因为pytest_status是对您更改的变量的引用,而不是变量本身。。上帝是否有办法在它们之间共享变量?有关如何使用
Value
Array
的示例,请参阅。请记住:如果您有一个全局变量“a”,并在函数中使用它,则后一个变量只是全局变量的副本。如果你真的想改变全局变量的内容,你必须写一次“全局a”!这不适用于您的代码,因为pytest_status是对您更改的变量的引用,而不是变量本身。除了线程/进程问题外,您还需要在更新和打印对象时锁定对该对象的访问。(在
+=1
不是原子的情况下,以及为了确保print语句具有正确的值。)@chepner但当我使用lock时。。无法获取锁的进程只跳过代码的锁定部分?!听起来。。。错。锁应该会导致进程阻塞,直到它们能够获取锁并执行受保护的代码。否则,您不知道哪些进程可能执行了代码,或者单个进程是否执行了特定的块。除了线程/进程问题之外,您还需要在更新和打印对象时锁定对该对象的访问。(在
+=1
不是原子的情况下,以及为了确保print语句具有正确的值。)@chepner但当我使用lock时。。无法获取锁的进程只跳过代码的锁定部分?!听起来。。。错。锁应该会导致进程阻塞,直到它们能够获取锁并执行受保护的代码。否则,您不知道哪些进程可能执行了代码,也不知道单个进程是否执行了特定的块。事实上,是的,但我认为这是一个设计过度的解决方案,在python中应该是这方面的标准解决方案。Daniel提供的值和数组看起来不错。完全忘记它。事实上是的,但我认为这是一个过度工程化的解决方案,在python中应该是这个问题的标准解决方案。Daniel提供的值和数组看起来不错。完全忘记它。
import subprocess
from multiprocessing import Pool, Lock

pytest_status = {
    'finished' : 0,
    'total'    : 0
}

print_lock = Lock()

def run_test(test):
    status = subprocess.call(...)

    global pytest_status
    pytest_status['finished'] += 1

    print_lock.acquire()
    print 'test ' + str(pytest_status['finished']) + '/' + str(pytest_status['total']) + ': ' + ('success' if status == 0 else 'failure')    
    print_lock.release()

def main():
    params = [...]

    global pytest_status    
    pytest_status['total'] = len(params)

    print 'will perform ' + str(pytest_status['total']) + ' tests'

    pool = Pool(30)
    pool.map(run_test, params)
    pool.close()
    pool.join()

if __name__ == '__main__':
    main()