好的,我一直在玩一些代码,部分是为了更好地理解python,部分是为了从网上抓取一些数据。如果使用Python Multiprocessing和Pool,我想了解的部分内容。
我已经掌握了基础知识,但是因为我首先编写了单线程程序,然后移动到使用池来多线程化进程,我有全局变量,并调用全局定义的函数。我猜这两个都不好,但在网上搜索,事情似乎变得非常复杂,或者没有回答我的问题。
任何人都可以首先确认全局变量是坏的,并且可能导致问题,对我来说这是有道理的,因为两个线程可以同时访问同一个变量,因此存在问题。
其次,如果我有一个全局定义的函数,为了参数处理一个字符串并使用标准字符串函数返回它,是否可以在池进程中调用它?
答案 0 :(得分:0)
当涉及如何访问变量和函数时,多线程和多处理是完全不同的。单独的进程(多处理)具有不同的存储空间,因此根本无法访问相同(实例)的函数或变量,因此全局变量的概念并不存在。在进程之间共享数据必须通过可以为您传递数据的管道或队列来完成。主进程和子进程都可以访问同一个队列,因此在某种程度上你可以将其视为一种全局变量。
使用多线程,您绝对可以访问全局变量,如果您的程序很简单,它可以是一个很好的编程方式。例如,子线程可以读取主线程中变量的值,并将其用作子线程函数中的标志。但是,您需要了解线程安全操作;就像你说同一个对象上的多个线程的复杂操作可能会导致冲突。在这种情况下,您需要使用线程锁定或其他一些安全方法。然而,许多操作自然是原子的,因此线程安全,例如读取单个变量。有一个很好的线程安全操作和线程同步列表on this page。
通常使用多处理和多线程,您需要将一些耗时的函数传递给线程或进程,但它们不会重新运行该函数的同一实例。下面的示例显示了以原子方式访问全局变量的多个线程的有效用例。然而,单独的过程却无法实现。
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()