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,最后我们设置日志记录器的级别并传递消息。