好吧,我一直在玩一些代码,一方面是为了更好地理解python,另一方面是从网络上获取一些数据。如果使用Python多处理器和Pool,我想了解的部分内容。
我已经完成了基本的工作,但是,因为我首先编写了单线程过程,然后转向使用池到多线程过程。在这个过程中,我既有全局变量,也有对全局定义函数的调用。我猜这两者都很糟糕,但在网上搜索时,事情似乎变得非常复杂,或者很快就无法回答我的问题。
有人能首先确认全局变量是坏的,可能会导致问题吗?对我来说,这是有道理的,因为两个线程可以同时访问同一个变量,因此会出现问题。
其次,如果我有一个全局定义的函数,为了参数的目的,它处理一个字符串并使用标准字符串函数返回它,可以在池进程中调用它吗?
当涉及到如何访问变量和函数时,多线程和多处理是截然不同的。单独的进程(多处理)具有不同的内存空间,因此无法访问相同的函数或变量(的实例),因此全局变量的概念并不真正存在。进程之间的数据共享必须通过可以为您传递数据的管道或队列来完成。不过,主进程和子进程都可以访问同一个队列,因此在某种程度上,您可以将其视为一种全局变量。
有了多线程,你肯定可以访问全局变量,如果你的程序很简单,这是一种很好的编程方式。例如,子线程可以读取主线程中变量的值,并将其用作子线程函数中的标志。但是,您需要了解线程安全操作;就像您所说的,多个线程对同一对象执行复杂操作可能会导致冲突。在这种情况下,您需要使用线程锁定或其他一些安全的方法。然而,许多操作自然是原子操作,因此是线程安全的,例如读取单个变量。这个页面上有一个很好的线程安全操作和线程同步列表。
通常,对于多处理和多线程,您会将一些耗时的函数传递给线程或进程,但它们不会重新运行该函数的同一实例。以下示例显示了多个线程原子访问全局变量的有效用例。然而,单独的过程将无法。
import multiprocessing as mp
import threading
import time
work_flag = True
def worker_func():
global work_flag
while True:
if work_flag:
# do stuff
time.sleep(1)
print mp.current_process().name, 'working, work_flag =', work_flag
else:
time.sleep(0.1)
def main():
global work_flag
# processes can't access the same "instance" of work_flag!
process = mp.Process(target = worker_func)
process.daemon = True
process.start()
# threads can safely read global work_flag
thread = threading.Thread(target = worker_func)
thread.daemon = True
thread.start()
while True:
time.sleep(3)
# changing this flag will stop the thread, but not the process
work_flag = False
if __name__ == '__main__':
main()