Python中的多处理

多处理程序包支持生成过程。它是指加载和执行新的子进程的函数。为了让孩子终止或继续执行并发计算,则当前进程必须使用类似于线程模块的API等待。

介绍

当我们使用Multiprocessing时,首先要创建过程对象。然后,它调用一个start()方法。

范例程式码

from multiprocessing import Process
   def display():
      print ('Hi !! I am Python')
      if __name__ == '__main__':
      p = Process(target=display)
      p.start()
      p.join()

在此示例中,首先我们导入Process类,然后使用该display()函数启动Process对象。

然后,用start()方法开始处理,然后用该join()方法完成处理。

我们还可以使用args关键字将参数传递给函数。

示例

from multiprocessing import Process
   def display(my_name):
   print ('Hi !!!' + " " + my_name)
   if __name__ == '__main__':
      p = Process(target=display, args=('Python',))
      p.start()
      p.join()

在此示例中,我们创建一个过程,该过程计算数字的立方并将所有结果打印到控制台。

范例程式码

from multiprocessing import Process
   def cube(x):
      for x in my_numbers:
         print('%s cube is %s' % (x, x**3))
      if __name__ == '__main__':
         my_numbers = [3, 4, 5, 6, 7, 8]
         p = Process(target=cube, args=('x',))
         p.start()
p.join
print ("Done")

输出结果

Done
3 cube is 27
4 cube is 64
5 cube is 125
6 cube is 216
7 cube is 343
8 cube is 512

我们也可以一次创建多个流程。

在此示例中,首先我们创建一个进程,即process1,该进程仅计算一个数字的立方,与此同时,第二个进程process2正在检查该数字是偶数还是奇数。

示例

from multiprocessing import Process
def cube(x):
   for x in my_numbers:
   print('%s cube is %s' % (x, x**3))
def evenno(x):
   for x in my_numbers:
   if x % 2 == 0:
   print('%s is an even number ' % (x))
   if __name__ == '__main__':
      my_numbers = [3, 4, 5, 6, 7, 8]
      my_process1 = Process(target=cube, args=('x',))
      my_process2 = Process(target=evenno, args=('x',))
      my_process1.start()
      my_process2.start()
      my_process1.join()
   my_process2.join()
print ("Done")

输出结果

3 cube is 27
4 cube is 64
5 cube is 125
6 cube is 216
7 cube is 343
8 cube is 512
4 is an even number
6 is an even number
8 is an even number
Done

流程之间的沟通

多处理支持管道和队列,这是进程之间的两种通信通道。

管子

在多处理中,当我们要在进程之间进行通信时,在这种情况下使用管道

示例

from multiprocessing import Process, Pipe
   def myfunction(conn):
      conn.send(['hi!! I am Python'])
      conn.close()
      if __name__ == '__main__':
         parent_conn, child_conn = Pipe()         p = Process(target=myfunction, args=(child_conn,))
         p.start()
      print (parent_conn.recv() )
p.join()

输出结果

['hi !!! I am Python']

管道返回两个连接对象,它们代表管道的两端。每个连接对象都有两种方法send(),一种是recv()方法,另一种是方法。

在此示例中,首先我们创建一个过程,该过程打印消息“ hi !! I am Python”,然后共享数据。

s列

当我们在进程之间传递数据时,那时我们可以使用Queue对象。

示例

import multiprocessing
   def evenno(numbers, q):
      for n in numbers:
      if n % 2 == 0:
      q.put(n)
      if __name__ == "__main__":
         q = multiprocessing.Queue()
         p = multiprocessing.Process(target=evenno, args=(range(10), q))
         p.start()
         p.join()
   while q:
print(q.get())

输出结果

0
2
4
6
8

在此示例中,首先创建一个检查天气是否为偶数的函数。如果数字是偶数,则将其插入队列的末尾。然后,我们创建一个队列对象和一个流程对象,然后启动流程。

最后检查队列是否为空。

当我们打印数字时,首先我们打印在队列前面的值,然后打印下一个,依此类推。

锁具

在这种情况下,如果我们希望一次只执行一个进程,则使用Locks。这意味着时间会阻止其他进程执行类似的代码。该过程完成后,将释放锁定。

使用Locks方法的示例

示例

from multiprocessing import Process, Lock
def dispmay_name(l, i):
l.acquire()
print ('Hi', i)
   l.release()
if __name__ == '__main__':
   my_lock = Lock()   my_name = ['Aadrika', 'Adwaita', 'Sakya', 'Sanj']
for name in my_name:
Process(target=dispmay_name, args=(my_lock,name)).start()

输出结果

Hi Aadrika
Hi Adwaita
Hi Sakya
Hi Sanj

记录中

多处理模块还提供了日志记录模块,以确保如果日志记录包不使用锁功能,则在执行过程中进程之间的消息会混合在一起。

示例

import multiprocessing, logging
logger = multiprocessing.log_to_stderr()
logger.setLevel(logging.INFO)
logger.warning('Error has occurred')

在此示例中,首先导入日志记录和多处理模块,然后使用multiprocessing.log_to_stderr()方法。然后调用get_logger()并添加到sys.stderr中,最后我们设置记录器的级别并传递消息。