Python多处理示例
在本教程中,我们将通过示例学习Python多重处理。
Python多处理
如今,并行处理越来越受到关注。
如果您仍然不了解并行处理,请向维基百科学习。
随着CPU制造商开始向其处理器中添加越来越多的内核,创建并行代码是提高性能的好方法。
Python引入了多处理模块,使我们可以编写并行代码。
要了解此模块的主要动机,我们必须了解有关并行编程的一些基础知识。
阅读本文后,我们希望您能够收集有关此主题的一些知识。
Python多处理进程,队列和锁
python多重处理模块中有许多类可用于构建并行程序。
其中有三个基本类:"进程","队列"和"锁"。
这些类将帮助您构建并行程序。
但是在描述这些内容之前,让我们用简单的代码启动该主题。
为了使并行程序有用,您必须知道您的PC中有多少个内核。
Python Multiprocessing模块使您知道这一点。
以下简单代码将打印您PC中的内核数。
import multiprocessing print("Number of cpu : ", multiprocessing.cpu_count())
以下输出可能因您的电脑而异。
对我来说,核心数是8。
Python多处理Process类
Python多处理" Process"类是一种抽象,它建立了另一个Python进程,提供了它运行代码的方式,并为父应用程序控制执行提供了一种方法。
属于Process类的两个重要函数是start()和join()函数。
首先,我们需要编写一个将由进程运行的函数。
然后,我们需要实例化一个流程对象。
如果我们创建一个过程对象,那么直到我们通过start()
函数告诉它开始处理之前,什么都不会发生。
然后,该过程将运行并返回其结果。
之后,我们通过join()
函数告诉过程完成。
如果没有join()
函数调用,进程将保持空闲状态,并且不会终止。
因此,如果您创建许多流程而没有终止它们,则可能会面临资源短缺。
然后,您可能需要手动杀死它们。
重要的一件事是,如果您想在过程中传递任何参数,则需要使用" args"关键字参数。
以下代码将有助于理解Process类的用法。
from multiprocessing import Process def print_func(continent='Asia'): print('The name of continent is : ', continent) if __name__ == "__main__": # confirms that the code is under main function names = ['America', 'Europe', 'Africa'] procs = [] proc = Process(target=print_func) # instantiating without any argument procs.append(proc) proc.start() # instantiating process with arguments for name in names: # print(name) proc = Process(target=print_func, args=(name,)) procs.append(proc) proc.start() # complete the processes for proc in procs: proc.join()
Python多处理Queue类
您具有有关计算机数据结构的基本知识,您可能也了解Queue。
Python多重处理模块提供了" Queue"类,该类正是先进先出数据结构。
它们可以存储任何pickle的Python对象(尽管最好是简单的对象),并且对于在进程之间共享数据非常有用。
当队列作为参数传递给流程的目标函数以使流程能够使用数据时,队列特别有用。
通过使用put函数,我们可以将数据插入队列中,然后使用get函数,可以从队列中获取数据。
请参见以下代码以获取快速示例。
from multiprocessing import Queue colors = ['red', 'green', 'blue', 'black'] cnt = 1 # instantiating a queue object queue = Queue() print('pushing items to queue:') for color in colors: print('item no: ', cnt, ' ', color) queue.put(color) cnt += 1 print('\npopping items from queue:') cnt = 0 while not queue.empty(): print('item no: ', cnt, ' ', queue.get()) cnt += 1
Python多处理锁类
Lock类的任务非常简单。
它允许代码声明锁,以便在释放锁之前,没有其他进程可以执行类似的代码。
因此,Lock类的任务主要是两个。
一种是要求锁定,另一种是释放锁定。
要声明锁定,使用acquire()
函数,并使用释放release()
函数。
Python多处理示例
在这个Python多处理示例中,我们将所有知识融合在一起。
假设我们要完成一些任务。
为了完成该任务,我们将使用几个过程。
因此,我们将维持两个队列。
一个将包含任务,另一个将包含已完成任务的日志。
然后,我们实例化流程以完成任务。
请注意,python Queue类已经同步。
也就是说,我们不需要使用Lock类来阻止多个进程访问同一队列对象。
因此,在这种情况下,我们不需要使用Lock类。
下面是将任务添加到队列中,然后创建进程并启动它们,然后使用join()完成该过程的实现。
最后,我们从第二个队列中打印日志。
from multiprocessing import Lock, Process, Queue, current_process import time import queue # imported for using queue.Empty exception def do_job(tasks_to_accomplish, tasks_that_are_done): while True: try: ''' try to get task from the queue. get_nowait() function will raise queue.Empty exception if the queue is empty. queue(False) function would do the same task also. ''' task = tasks_to_accomplish.get_nowait() except queue.Empty: break else: ''' if no exception has been raised, add the task completion message to task_that_are_done queue ''' print(task) tasks_that_are_done.put(task + ' is done by ' + current_process().name) time.sleep(.5) return True def main(): number_of_task = 10 number_of_processes = 4 tasks_to_accomplish = Queue() tasks_that_are_done = Queue() processes = [] for i in range(number_of_task): tasks_to_accomplish.put("Task no " + str(i)) # creating processes for w in range(number_of_processes): p = Process(target=do_job, args=(tasks_to_accomplish, tasks_that_are_done)) processes.append(p) p.start() # completing process for p in processes: p.join() # print the output while not tasks_that_are_done.empty(): print(tasks_that_are_done.get()) return True if __name__ == '__main__': main()
根据任务的数量,代码将需要一些时间来显示输出。
以下代码的输出将不时变化。
Python多处理池
Python多处理池可用于跨多个输入值并行执行功能,从而跨进程分配输入数据(数据并行性)。
下面是一个简单的Python多处理池示例。
from multiprocessing import Pool import time work = (["A", 5], ["B", 2], ["C", 1], ["D", 3]) def work_log(work_data): print(" Process %s waiting %s seconds" % (work_data[0], work_data[1])) time.sleep(int(work_data[1])) print(" Process %s Finished." % work_data[0]) def pool_handler(): p = Pool(2) p.map(work_log, work) if __name__ == '__main__': pool_handler()
注意池的大小为2,所以两个work_log函数并行执行。
当函数处理之一完成时,它将选择下一个参数,依此类推。