Python中的多进程


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

简介

当我们使用多进程时,首先创建 **进程** 对象。然后它调用 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 关键字将参数传递给函数。

Learn Python in-depth with real-world projects through our Python certification course. Enroll and become a certified expert to boost your career.

示例

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”,然后共享数据。

队列

当我们在进程之间传递数据时,我们可以使用 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

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

最后检查队列是否为空。

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

当我们希望一次只执行一个进程时,可以使用锁。这意味着该时间阻止其他进程执行类似的代码。在进程完成后,锁将被释放。

使用锁方法的示例

示例

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

日志记录

multiprocessing 模块还提供日志记录模块,以确保如果日志记录包不使用锁函数,则进程之间的消息在执行期间不会混合。

示例

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

在这个例子中,我们首先导入 logging 和 multiprocessing 模块,然后使用 multiprocessing.log_to_stderr() 方法。它还调用 get_logger() 以及添加到 sys.stderr,最后我们设置日志记录器的级别并传递消息。

更新于: 2020年6月26日

5K+ 浏览量

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告