Python 多处理日志记录
本文将讨论 multiprocessing 的概念。 在此之后,我们将讨论 Python 中的多处理和使用 Python 代码进行多处理的日志处理。
多重处理
多处理是一种计算范例,其中多个处理器同时处理同一程序的不同部分。
在多进程操作系统中运行的应用程序被分成更小的子程序,通过分配到不同的处理器中独立运行以提高性能。
多重处理有两种不同的类型:
- 对称多处理:在这种多处理技术中,单个操作系统管理多个具有共享主内存的计算机处理器。 通常,具有多处理能力的计算机系统支持对称多处理。
- 非对称多处理:在这种多处理中,分配一个计算机处理器来处理与操作系统相关的任务,而另一个计算机处理器则分配与应用程序相关的任务。 与对称多处理相比,它被认为是低效的,因为在非对称多处理中,一个处理器可能空闲,而另一个处理器可能在同一时间间隔内完全忙碌。
Python 中的多处理
在 Python 中,多处理库用于多处理任务。
考虑以下示例:
import multiprocessing
def func1(arg):
print("func1: with parameter",arg)
def func2(arg):
print("func2: with parameter",arg)
if __name__ == "__main__":
process1 = multiprocessing.Process(target=func1, args=(1,))
process2 = multiprocessing.Process(target=func2, args=(2,))
process1.start()
process2.start()
process1.join()
process2.join()
print("Processes Ended")
在上面的代码中,我们使用 import multiprocessing 来包含 multiprocessing 模块。 Process 类对象用于创建进程。
进程类对象接收目标(在进程中运行的函数)作为参数和 args 作为目标函数的参数。
Process 类的启动方法用于启动进程。 在上面的例子中,我们启动了两个进程。
我们使用 join 方法继续执行当前程序,直到 process1 和 process2 没有终止。
一旦 process1 和 process2 完成它们的任务,当前程序运行 print("Processes Ended") 语句。
上述程序的输出如下:
func1: with parameter 1
func2: with parameter 2
Processes Ended
多处理期间 Python 中的进程 ID
我们还可以使用两种不同的方法打印进程 ID (PID)。
- os.getpid()
- 进程类对象成员变量pid
考虑以下代码:
import multiprocessing
import os
def func1(arg):
print("func1: with parameter ",arg)
print("ID of func1 process:", os.getpid())
def func2(arg):
print("func2: with parameter ",arg)
print("ID of func2 process:", os.getpid())
if __name__ == "__main__":
process1 = multiprocessing.Process(target=func1, args=(1,))
process2 = multiprocessing.Process(target=func2, args=(2,))
process1.start()
process2.start()
print ("Process 1 / function 1 PID: ",process1.pid)
print("Process 2 / function 2 PID: ", process2.pid)
process1.join()
process2.join()
print("Processes Ended")
在上面的示例中,os.getpid()
和 process1.pid 显示了进程 ID。 以下代码的输出如下:
Process 1 / function 1 PID: 11368
Process 2 / function 2 PID: 14876
func1: with parameter 1
ID of func1 process: 11368
func2: with parameter 2
ID of func2 process: 14876
Processes Ended
os.getpid()
和 process1.pid 显示相同的进程 ID。
Pool 类的多处理
Python 多处理模块的 Pool 类用于并行执行具有不同输入值的相同函数。 例如,考虑以下代码:
import multiprocessing
def func1(arg):
print("func1: with parameter ",arg)
if __name__ == '__main__':
process_pool = multiprocessing.Pool(3)
process_pool.map(func1, [1,2,3])
process_pool.close()
process_pool.join()
In the above code, multiprocessing.Pool creates three processes to call func1 with different arguments. The output of the following code is as follows:
func1: with parameter 1
func1: with parameter 2
func1: with parameter 3
Python 中的多处理日志记录
我们可以使用 Python 的多进程库记录来自多个进程的信息。 记录多处理有不同的方法。
我们可以使用 Python 中的 logging.handlers、QueueHandler 和 QueueListener 类来进行日志记录。
考虑以下代码:
import multiprocessing
import logging
import os
from logging.handlers import QueueHandler, QueueListener
def func(arg):
logging.info('Process/function with argument {} and PID {}'.format(arg, os.getpid()))
def Process_init(q):
queue_handler = QueueHandler(q)
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(queue_handler)
if __name__ == '__main__':
print ('Main Started')
mp_queue = multiprocessing.Queue()
lg_handler = logging.StreamHandler()
lg_handler.setFormatter(logging.Formatter("%(levelname)s: %(asctime)s - %(process)s - %(message)s"))
queue_listener = QueueListener(mp_queue, lg_handler)
queue_listener.start()
process_pool = multiprocessing.Pool(2, Process_init, [mp_queue])
process_pool.map(func, [1, 2])
process_pool.close()
process_pool.join()
queue_listener.stop()
print ('Main Ended')
上面的代码定义了一个接受一个参数的函数 func。
func 方法记录一个具有参数值和进程 ID 的字符串。 我们使用 os.getpid() 获取进程 ID。
在 main 方法中,我们为 QueueListener 创建 multiprocessing.Queue()
和 logging.StreamHandler()
对象。 handler.setFormatter
用于设置日志格式。
我们使用 multiprocessing.Pool 对象创建两个进程,并以 1 和 2 作为参数值在两个进程中调用 func 方法。
Process_init 方法用于初始化queue_handler。 上述代码的输出如下:
上面的代码显示了进程 ID 为 7024 和 15680 的两个进程的日志信息。
我们还可以通过将 lg_handler = logging.StreamHandler()
语句替换为 lg_handler = logging.FileHandler('info.log') 来将信息记录到日志文件中。
logging.FileHandler 创建文件 info.log 并将日志存储在 info.log 文件中。
相关文章
Python multiprocessing 共享对象
发布时间:2023/06/13 浏览次数:81 分类:Python
-
在 Python 中,共享内存多处理由连接多个处理器组成,但这些处理器必须能够直接访问系统的主内存。 这将允许所有连接的处理器访问它们使用或创建的其他处理器数据。
在 Python Lambda 中使用 Await
发布时间:2023/06/13 浏览次数:143 分类:Python
-
在 Python 中,要实现异步编程,我们可以将 async/await 特性与函数一起使用,但我们使用 lambda 函数来实现。 本文将讨论在 Python lambda 函数中使用 await 的可能性。Python Lamda 中没有async/await lambda
Python Lambda 闭包
发布时间:2023/06/13 浏览次数:141 分类:Python
-
本篇文章将介绍在 Python 中使用 lambda 函数和闭包。在 Python 中使用 Lambda 函数的语法
Python 中的最长公共子序列
发布时间:2023/06/02 浏览次数:147 分类:Python
-
本篇文章讲介绍在 Python 中查找两个序列之间最长公共子序列的长度。使用 Naive 方法在 Python 中查找最长公共子序列;使用动态规划在 Python 中查找最长公共子序列
在 Python 请求中使用 Cookie
发布时间:2023/06/02 浏览次数:98 分类:Python
-
本篇文章介绍如何使用 requests.get() 借助 Python 中的 cookies 参数获取 cookies,以及如何访问需要登录的特定网页。
在 Python 中带有参数的请求查询字符串
发布时间:2023/06/02 浏览次数:174 分类:Python
-
本篇文章将介绍在使用 Python 中的请求库创建请求时查询字符串参数的使用。在 Python 中使用参数查询请求的字符串
在 Python 中设置请求的最大重试次数
发布时间:2023/06/02 浏览次数:67 分类:Python
-
本教程描述了为什么我们会收到错误消息,指出超出了最大重试次数,以及我们如何在 Python 中为请求设置 max_retries。 如果服务器上的负载导致此错误,它还会为我们提供提示。
在 Python 中使用requests模块发布表单数据
发布时间:2023/06/02 浏览次数:184 分类:Python
-
本篇文章介绍了 Python requests 模块,并说明了我们如何使用该模块在 Python 中发布表单数据。使用 requests 模块在 Python 中发布表单数据
在 Python 中使用令牌进行 API 调用
发布时间:2023/06/02 浏览次数:149 分类:Python
-
在 Python 中进行不带令牌的 API 调用 要启动,我们需要先安装一个 Python 库来处理这个请求; 当我们在 Python 中调用 API 时,我们可以使用令牌来调用