多进程:

  • torch.utils.data.DataLoader()中的参数num_works代表进程数,如果为0,代表在主进程中,一般不会有多进程问题。

  • 主程序保护:在Windows系统中,子进程的创建和启动机制与UNIX系统不同。因此,必须使用if __name__ == "__main__":来保护代码块,以防止在子进程中执行不必要的代码。Windows中每个进程都从头开始执行脚本,而UNIX系统中则只会创建一个新的子进程。

  • 下面是来自ChatGPT 4o mini的回答:

    在Python中使用多进程来实现并发编程时,你需要注意以下几个方面:

    1. 使用multiprocessing模块:Python标准库中的multiprocessing模块提供了进程创建和管理的功能。它可以用来创建和管理子进程、交换数据等。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      from multiprocessing import Process

      def worker():
      print("Worker process")

      if __name__ == "__main__":
      p = Process(target=worker)
      p.start()
      p.join()
    2. 主程序保护:在Windows系统中,子进程的创建和启动机制与UNIX系统不同。因此,必须使用if __name__ == "__main__":来保护代码块,以防止在子进程中执行不必要的代码。Windows中每个进程都从头开始执行脚本,而UNIX系统中则只会创建一个新的子进程。

    3. 数据共享:在多进程环境中,进程之间的数据是隔离的。为了在进程之间共享数据,你可以使用multiprocessing模块提供的共享数据结构,如ValueArrayManager。例如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      from multiprocessing import Process, Value, Array

      def modify_data(num, arr):
      num.value += 1
      for i in range(len(arr)):
      arr[i] *= 2

      if __name__ == "__main__":
      num = Value('i', 0)
      arr = Array('i', range(10))

      p = Process(target=modify_data, args=(num, arr))
      p.start()
      p.join()

      print(num.value) # 输出修改后的值
      print(arr[:]) # 输出修改后的数组
    4. 进程间通信(IPC):如果进程需要通信,可以使用multiprocessing模块中的QueuePipeEventLock等机制进行进程间通信和同步。例如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      from multiprocessing import Process, Queue

      def worker(q):
      q.put("Hello from the worker")

      if __name__ == "__main__":
      q = Queue()
      p = Process(target=worker, args=(q,))
      p.start()
      print(q.get()) # 输出 "Hello from the worker"
      p.join()
    5. 进程池:如果你需要创建和管理大量的进程,可以使用multiprocessing.Pool类,它允许你创建一个进程池,并将任务分配到池中的进程上。Pool类提供了mapapply等方法来简化并发任务的处理:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      from multiprocessing import Pool

      def square(x):
      return x * x

      if __name__ == "__main__":
      with Pool(4) as p:
      result = p.map(square, [1, 2, 3, 4])
      print(result) # 输出 [1, 4, 9, 16]
    6. 避免死锁和竞争条件:在多进程编程中,多个进程可能会尝试同时访问共享资源,导致死锁或竞争条件。使用LockSemaphore等同步原语来协调对共享资源的访问,避免这些问题。

    7. 性能和开销:多进程比多线程更能利用多核CPU,但进程创建和销毁的开销比线程大。确保你的应用程序确实需要使用多进程,并权衡性能和复杂性。

    8. 调试困难:调试多进程应用程序可能比较困难,因为每个进程都有自己的执行上下文。使用日志记录或其他调试工具来帮助追踪问题。

    通过注意这些要点,你可以更有效地利用Python的多进程功能,提高程序的并发性能。