我目前尝试使用线程编写一个更大的python程序,但遇到了这样一个问题:数组不必以某种方式声明为全局的。在
import numpy as np
import threading
import time
import ctypes
import multiprocessing
import random
import os
def child1():
#global var
starttime = time.time()
for ite in range(10):
#data_np[ite] = time.time()-starttime
#print data_np[ite]
var += 1
print var
time.sleep(1)
def child2():
#global var
for ite in range(10):
#print data_np
print var
print "\n"
time.sleep(1)
os.system("clear")
data_np = np.zeros(shape=(10), dtype="float")
var = 0
thread1 = threading.Thread(target=child1)
thread2 = threading.Thread(target=child2)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
上述代码将产生一条错误消息,因为var没有声明为全局变量。取消注释
^{pr2}$生成一个可执行脚本,将var值打印两次。 但是当使用numpy数组数据时,没有声明
global data_np
是需要的。不过,脚本仍将运行。 我不理解这种行为。有人能解释一下吗?在
需要使用
global
语句来通知Python您希望将一个变量(var
)作为全局的、通用的可修改名称而不是每个函数的局部变量来处理。如果您将var = 0
定义移到函数之上,情况会稍微好一些:但作为Marcin says,“上帝的爱,不要这样做。”绕开几个
NameError
并不是这里的关键问题。在许多程序中,即使没有并发,全局变量也很难管理。在同时发生的环境中,它们会变成噩梦。它们的行为在线程化和多处理并发性(这两个都是你导入的,尽管你现在似乎在使用线程)和跨不同的平台(例如,Windows的工作方式与Unix/Linux/macosx不同)。在数组引用起作用的原因,至少在某种程度上是这样的:全局结构(例如字典、列表、NumPy数组)的内部内容很容易被修改,即使整个结构不是这样。其中大部分与Python如何管理名称(粗略地说,“变量”)有关,而不是与并发性有关。但是在一个并发的环境中,对这些全局结构的修改将很快变得危险(读起来:令人困惑、不可靠、不易复制)。在
所以,长话短说,在我们开始讨论race condition你的线程所面对的问题之前,这里很容易有三到四个重叠的问题。在
如果你的阅读器(
child2
)比你的编写器(child1
)有更长的睡眠时间,你也许可以得到基本上正常工作的代码。但是要注意:除了一个玩具示例,您需要一个真正的并发感知结构(例如a queue)。在global
用于允许分配全局变量。您可以读取没有此声明的全局变量。别为上帝的爱而做。阅读管理并发的技术。
相关问题 更多 >
编程相关推荐