首页 > 系统相关 >【多进程并发笔记】Python-Multiprocess

【多进程并发笔记】Python-Multiprocess

时间:2024-06-01 11:34:05浏览次数:23  
标签:Process Multiprocess False start Python alive 并发 time process

目录

调用函数后,函数内的变量如何释放?

在 Python 中,函数内部的局部变量在函数执行完毕后会被释放.这是因为函数内的局部变量只在函数执行期间存在,当函数执行完毕后,这些局部变量所占用的内存空间会被自动释放.

def my_function():
    # 在函数内部定义一个局部变量
    message = "Hello, World!"
    print(message)

# 调用函数
my_function()

# 函数执行完毕后,局部变量 message 被释放

在这个例子中,当函数 my_function 执行完毕后,局部变量 message 被释放,不再占用内存空间.

需要注意的是:函数内部的变量释放并不意味着函数返回值所占用的内存会被释放.

如果函数返回了一个引用类型的对象(如列表、字典等),这个对象在函数执行完毕后仍然可以被外部代码所引用,直到没有任何引用指向它时,Python 的垃圾回收机制才会将其释放.

总之,函数内的局部变量会在函数执行完毕后被释放,但返回值所占用的内存空间的释放取决于对象是否还被引用.

python2.7怎么使用多线程加速for loop

在 Python 2.7 中,你可以使用 threading 模块来实现多线程加速 for 循环.在 Python 2.7 中,threading 是用来创建和管理线程的内置模块.在 for 循环中使用多线程可以加速处理大量数据或者 IO 密集型任务.

以下是一个简单的示例,演示了如何在 Python 2.7 中使用多线程来加速 for 循环:

import threading

# 定义一个函数,用于并发执行的任务
def process_data(data):
    # 这里可以放入需要处理的任务
    print("Processing data:", data)

# 假设有一个包含需要处理数据的列表
data_list = [1, 2, 3, 4, 5]

# 创建线程列表
threads = []

# 创建并启动线程
for data in data_list:
    # 创建线程,并将函数和数据作为参数传递给线程的构造函数
    t = threading.Thread(target=process_data, args=(data,))
    threads.append(t)
    t.start()

# 等待所有线程执行完毕
for t in threads:
    t.join()

print("All threads have finished processing")

在这个示例中,我们首先定义了一个处理数据的函数 process_data,然后创建了一个包含需要处理的数据的列表 data_list.接着,我们创建了多个线程,并将函数和数据作为参数传递给线程的构造函数 threading.Thread,然后启动这些线程并等待它们执行完毕.

需要注意的是,在 Python 2.7 中,由于全局解释器锁 (GIL) 的存在,多线程并不能有效地利用多核 CPU.如果想要充分利用多核 CPU,可以考虑使用 multiprocessing 模块来实现多进程加速.

总之,在 Python 2.7 中,你可以使用 threading 模块来在 for 循环中实现多线程加速,但要注意 GIL 对多线程并发执行的影响.

多进程进程池,函数序列化错误的处理

报错:

RuntimeError  File "C:\Python27\lib\multiprocessing\forking.py", line 258, in __init__
is not going to be frozen to produce a Windows executable.''')
            Attempt to start a new process before the current process
            has finished its bootstrapping phase.

            This probably means that you are on Windows and you have
            forgotten to use the proper idiom in the main module:

                if __name__ == '__main__':

这个错误是由于在使用 multiprocessing 模块时,Python 2.7 试图对函数进行序列化 (pickling) 以便在多个进程之间传递.然而,由于某些函数不是可以被序列化的(可被pickling),因此会导致报错.

为了解决这个问题,可以将需要并发执行的函数放在一个单独的文件中,然后使用 if __name__ == '__main__': 来保护多进程的主入口点,这样可以避免 Windows 下的报错.下面是一个修改后的示例:

# 在新的文件中定义需要并行执行的函数
# 例如,放在一个名为 parallel.py 的文件中
from multiprocessing import Pool

# 定义需要并行执行的任务
def process_data(data):
    # 这里可以放入需要处理的任务
    print("Processing data:", data)

# 添加保护主入口点的代码
if __name__ == "__main__":
    # 创建进程池
    with Pool() as pool:
        # 假设有一个包含需要处理数据的列表
        data_list = [1, 2, 3, 4, 5]

        # 并行执行任务
        pool.map(process_data, data_list)

然后在你的主程序中调用这个新的文件:

from multiprocessing import Pool
from parallel import process_data

if __name__ == "__main__":
    with Pool() as pool:
        data_list = [1, 2, 3, 4, 5]
        pool.map(process_data, data_list)

将并发执行的函数放在一个单独的文件中,并使用 if __name__ == '__main__': 来保护主入口点,可以解决在 Windows 下使用 multiprocessing 模块时的序列化错误.

Time模块计算程序运行时间

在 Python 中,你可以使用 time 模块来计算程序的运行时间.下面我将向你展示如何使用该模块来测量代码块的执行时间.

import time

# 记录开始时间
start_time = time.time()

# 在这里放置你想要测量执行时间的代码块
# 例如,一个耗时的计算任务或者一个函数的执行

# 记录结束时间
end_time = time.time()

# 计算时间差
execution_time = end_time - start_time
print("程序执行时间为:", execution_time, "秒")

在这个示例中,用 time.time() 记录了代码块开始和结束的时间戳,然后计算它们之间的差值,从而得到代码块的执行时间.

使用多进程,Start()后,如何获得返回值?

在 Python 中,进程池是可以直接得到返回值的,但使用多进程创建一个进程后,通常情况下无法直接获得函数的返回值,因为子进程和父进程是相互独立的.然而,你可以通过一些手段来获取子进程的返回值.

一种常用的方法是使用进程间通信(Inter-process Communication, IPC).在 Python 中,可以使用 multiprocessing 模块提供的队列(Queue)和管道(Pipe)来实现进程间通信,从而传递子进程的返回值给父进程.下面是一个示例:

import multiprocessing

# 定义一个函数,用于在子进程中执行
def process_func(queue):
    result = 42  # 这里可以是任何需要返回的值
    queue.put(result)  # 将结果放入队列中

if __name__ == "__main__":
    # 创建一个队列用于进程间通信
    queue = multiprocessing.Queue()

    # 创建子进程并启动
    process = multiprocessing.Process(target=process_func, args=(queue,))
    process.start()

    # 等待子进程执行完毕
    process.join()

    # 获取子进程返回的结果
    result = queue.get()

    print("子进程返回值:", result)

在这个示例中,我们在子进程中执行 process_func 函数,并将结果放入队列中.在父进程中,我们可以通过调用队列的 get 方法来获取子进程的返回值.

使用多进程并行,每个进程都将结果写入sqlite3数据库,可以么

可以使用多进程并行处理,在每个进程中将结果写入到 SQLite3 数据库.但需要注意的是,SQLite3 在写入时可能会有一些限制,因此在多进程环境下需要格外小心.

下面是一个简单的示例,演示了如何在多进程中将结果写入 SQLite3 数据库:

import sqlite3
import multiprocessing

# 定义一个函数,用于在子进程中执行
def write_to_database(process_id, result):
    # 连接数据库
    conn = sqlite3.connect('results.db')
    c = conn.cursor()

    # 执行写入操作
    c.execute("INSERT INTO results VALUES (?, ?)", (process_id, result))

    # 提交更改并关闭连接
    conn.commit()
    conn.close()

if __name__ == "__main__":
    # 创建一个 SQLite3 数据库
    conn = sqlite3.connect('results.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS results
                 (process_id INTEGER, result TEXT)''')
    conn.commit()
    conn.close()

    # 创建多个进程并启动
    processes = []
    for i in range(5):
        process = multiprocessing.Process(target=write_to_database, args=(i, f"Result {i}"))
        processes.append(process)
        process.start()

    # 等待所有子进程执行完毕
    for process in processes:
        process.join()

    print("所有进程已经执行完毕,结果已写入数据库")

在这个示例中,我们首先创建了一个 SQLite3 数据库,然后定义了一个函数 write_to_database,用于在每个子进程中执行数据库写入操作.在主程序中,我们创建了多个进程,每个进程将结果写入数据库.

需要注意的是,SQLite3 在多线程/多进程下有一些限制,具体表现取决于使用的 SQLite3 驱动程序.通常建议在多进程环境中谨慎地使用 SQLite3,并注意处理可能出现的并发访问问题.如果需要在多进程或多线程环境下执行大量数据库操作,考虑使用其他支持并发访问的数据库,如 PostgreSQL 或 MySQL.

python创建进程池

在 Python 中,你可以使用 multiprocessing 模块来创建进程池.进程池可以帮助你管理多个子进程,从而可以并发执行多个任务.

下面是一个简单的示例,演示了如何在 Python 中创建进程池:

import multiprocessing

# 定义一个函数,用于在子进程中执行
def process_func(data):
    result = data * 2  # 这里可以是任何需要处理的任务
    return result

if __name__ == "__main__":
    # 创建一个进程池,指定最大进程数为 4
    with multiprocessing.Pool(processes=4) as pool:
        # 定义一个需要处理的数据列表
        data_list = [1, 2, 3, 4, 5]

        # 并行执行任务,并获取结果
        results = pool.map(process_func, data_list)

        # 打印结果
        print("处理结果:", results)

在这个示例中,我们首先创建了一个进程池,指定最大进程数为 4.然后,我们定义了一个需要处理的数据列表 data_list,并使用 pool.map 方法并行执行了这些数据的处理,最后获取并打印了执行的结果.

通过使用进程池,你可以很方便地并发执行多个子任务,从而提高程序的执行效率.需要注意的是,进程池并不适用于所有类型的任务,比如对于 IO 密集型任务,有时候使用线程池可能会更加合适.

进程池的最大进程数怎么确定

确定进程池中进程的最大数量取决于多个因素,包括系统资源、任务类型和性能需求.

  1. CPU 核心数量:通常来说,进程池的最大进程数不应该超过CPU核心的数量.因为如果进程数超过了 CPU 核心数量,就会导致进程上下文切换频繁,从而降低整体性能.

  2. 任务类型:如果你的任务是 CPU 密集型的,即任务需要大量的 CPU 计算资源,那么通常可以根据 CPU 核心数量来确定最大进程数.如果任务是 IO 密集型的,即任务需要大量的 IO 操作,可以允许更多的进程,因为 IO 操作通常会释放 CPU 的执行时间,允许更多的进程并发执行.

  3. 内存和其他资源:每个进程都会消耗系统资源,包括内存、文件描述符等.因此,你需要考虑系统的可用资源来确定最大进程数.如果系统资源不足,进程数过多会导致系统性能下降甚至崩溃.

  4. 性能需求:有时候,为了提高任务执行速度,可以略微增加进程池的最大进程数.在实际应用中,通常需要进行一些基准测试和性能优化,以确定最佳的进程池大小.

一般来说,初始时可以选择一个合理的进程池大小,进行性能测试和观察系统资源使用情况,根据实际情况逐步调整进程池大小,以取得最佳性能.

py2.7字典合并的办法

在 Python 2.7 中,你可以使用 update 方法来合并两个字典.这个方法将一个字典的内容更新到另一个字典中,如果存在相同的键,则以被更新字典中的值为准.

以下是一个示例,演示了如何在 Python 2.7 中合并两个字典:

# 定义两个字典
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

# 使用 update 方法合并字典
dict1.update(dict2)

print(dict1)

在这个示例中,dict1.update(dict2) 将字典 dict2 中的内容更新到了 dict1 中,最终得到了合并后的字典.此时,如果存在相同的键(例如 'b'),则以被更新字典中的值为准,因此最终的结果是 {'a': 1, 'b': 3, 'c': 4}.

除了 update 方法,你还可以使用字典解析和 ** 操作符来实现字典的合并.以下是另外一种合并字典的方法:

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

# 使用字典解析和 ** 操作符合并字典
merged_dict = {key: value for d in [dict1, dict2] for key, value in d.items()}

print(merged_dict)

无论使用哪种方法,这些技巧都可以帮助你在 Python 2.7 中实现字典的合并操作.

多进程的join()方法

在多进程中,当主进程等待子进程执行完毕时,可以使用 join() 方法来实现.


import multiprocessing

def create_items(pipe):
    send_c, recv_c = pipe
    import numpy as np
    import time
    # 函数计算得到一个数据结果
    data=np.random.rand(20,20)
    print("start time:{}, process name:{}".format(time.time(),multiprocessing.current_process().name))
    # send_c.send(data)
    time.sleep(0.5)
if __name__== '__main__':
    
    pipe_1 = multiprocessing.Pipe(True)
    ps=[]
    for i in range(20):
        p = multiprocessing.Process(target=create_items,name="Process-{}".format(i), args=(pipe_1,))
        ps.append(p)
        
    for p in ps:
        p.start()
        # print("Process-{} start,alive={}".format(p.name,p.is_alive()))
        # p.join()
        # print("Process-{} jion,alive={}".format(p.name,p.is_alive()))
        
    import time
    time.sleep(2)
    
    # _,recv_c = pipe_1
    # getdata=[]
    # for i in range(21):
    #     data = recv_c.recv()
    #     print(data.shape)
    #     getdata.append(data)
    # # print(data)
    for p in ps:
        print("Process-{} ,alive={}".format(p.name,p.is_alive()))
        p.terminate()
        print("Process-{} terminate,alive={}".format(p.name,p.is_alive()))

输出:

start time:1715848697.91, process name:Process-1
start time:1715848697.92, process name:Process-3
start time:1715848697.93, process name:Process-9
start time:1715848697.93, process name:Process-2
start time:1715848697.94, process name:Process-5
start time:1715848697.94, process name:Process-0
start time:1715848697.94, process name:Process-4
start time:1715848697.94, process name:Process-10
start time:1715848697.95, process name:Process-7
start time:1715848698.16, process name:Process-12
start time:1715848698.17, process name:Process-16
start time:1715848698.17, process name:Process-6
start time:1715848698.17, process name:Process-13
start time:1715848698.17, process name:Process-11
start time:1715848698.18, process name:Process-17
start time:1715848698.18, process name:Process-14
start time:1715848698.22, process name:Process-8
ssstart time:1715848698.22, process name:Process-18tart time:1715848698.22, process name:Process-15tart time:1715848698.22, process name:Process-19


Process-Process-0 ,alive=False
Process-Process-0 terminate,alive=False
Process-Process-1 ,alive=False
Process-Process-1 terminate,alive=False
Process-Process-2 ,alive=False
Process-Process-2 terminate,alive=False
Process-Process-3 ,alive=False
Process-Process-3 terminate,alive=False
Process-Process-4 ,alive=False
Process-Process-4 terminate,alive=False
Process-Process-5 ,alive=False
Process-Process-5 terminate,alive=False
Process-Process-6 ,alive=False
Process-Process-6 terminate,alive=False
Process-Process-7 ,alive=False
Process-Process-7 terminate,alive=False
Process-Process-8 ,alive=False
Process-Process-8 terminate,alive=False
Process-Process-9 ,alive=False
Process-Process-9 terminate,alive=False
Process-Process-10 ,alive=False
Process-Process-10 terminate,alive=False
Process-Process-11 ,alive=False
Process-Process-11 terminate,alive=False
Process-Process-12 ,alive=False
Process-Process-12 terminate,alive=False
Process-Process-13 ,alive=False
Process-Process-13 terminate,alive=False
Process-Process-14 ,alive=False
Process-Process-14 terminate,alive=False
Process-Process-15 ,alive=False
Process-Process-15 terminate,alive=False
Process-Process-16 ,alive=False
Process-Process-16 terminate,alive=False
Process-Process-17 ,alive=False
Process-Process-17 terminate,alive=False
Process-Process-18 ,alive=False
Process-Process-18 terminate,alive=False
Process-Process-19 ,alive=False
Process-Process-19 terminate,alive=False

在start()进程后,不加join()方法,那么每个进程开始启动计算的时间几乎一致.加入join()方法后,一个进程会等计算完成后才开始下一个进程.

# -*- coding: utf-8 -*-
import multiprocessing
from test import square,foo
def create_items(pipe):
    send_c, recv_c = pipe
    import numpy as np
    import time
    # 函数计算得到一个数据结果
    data=np.random.rand(20,20)
    print("start time:{}, process name:{}".format(time.time(),multiprocessing.current_process().name))
    # send_c.send(data)
    time.sleep(0.5)

if __name__== '__main__':
    
    pipe_1 = multiprocessing.Pipe(True)
    ps=[]
    for i in range(20):
        p = multiprocessing.Process(target=create_items,name="Process-{}".format(i), args=(pipe_1,))
        ps.append(p)
        
    for p in ps:
        p.start()
        print("Process-{} start,alive={}".format(p.name,p.is_alive()))
        p.join()
    import time
    time.sleep(2)
    print(ps[0].is_alive())
    for p in ps:
        print("Process-{} ,alive={}".format(p.name,p.is_alive()))
        time.sleep(0.5)
        p.terminate()
        print("Process-{} terminate,alive={}".format(p.name,p.is_alive()))

输出:

Process-Process-0 start,alive=True
start time:1715849085.02, process name:Process-0
Process-Process-1 start,alive=True
start time:1715849085.59, process name:Process-1
Process-Process-2 start,alive=True
start time:1715849086.18, process name:Process-2
Process-Process-3 start,alive=True
start time:1715849086.76, process name:Process-3
Process-Process-4 start,alive=True
start time:1715849087.34, process name:Process-4
Process-Process-5 start,alive=True
start time:1715849087.92, process name:Process-5
Process-Process-6 start,alive=True
start time:1715849088.51, process name:Process-6
Process-Process-7 start,alive=True
start time:1715849089.1, process name:Process-7
Process-Process-8 start,alive=True
start time:1715849089.67, process name:Process-8
Process-Process-9 start,alive=True
start time:1715849090.26, process name:Process-9
Process-Process-10 start,alive=True
start time:1715849090.84, process name:Process-10
Process-Process-11 start,alive=True
start time:1715849091.41, process name:Process-11
Process-Process-12 start,alive=True
start time:1715849092.0, process name:Process-12
Process-Process-13 start,alive=True
start time:1715849092.58, process name:Process-13
Process-Process-14 start,alive=True
start time:1715849093.16, process name:Process-14
Process-Process-15 start,alive=True
start time:1715849093.74, process name:Process-15
Process-Process-16 start,alive=True
start time:1715849094.32, process name:Process-16
Process-Process-17 start,alive=True
start time:1715849094.9, process name:Process-17
Process-Process-18 start,alive=True
start time:1715849095.49, process name:Process-18
Process-Process-19 start,alive=True
start time:1715849096.08, process name:Process-19
False
Process-Process-0 ,alive=False
Process-Process-0 terminate,alive=False
Process-Process-1 ,alive=False
Process-Process-1 terminate,alive=False
Process-Process-2 ,alive=False
Process-Process-2 terminate,alive=False
Process-Process-3 ,alive=False
Process-Process-3 terminate,alive=False
Process-Process-4 ,alive=False
Process-Process-4 terminate,alive=False
Process-Process-5 ,alive=False
Process-Process-5 terminate,alive=False
Process-Process-6 ,alive=False
Process-Process-6 terminate,alive=False
Process-Process-7 ,alive=False
Process-Process-7 terminate,alive=False
Process-Process-8 ,alive=False
Process-Process-8 terminate,alive=False
Process-Process-9 ,alive=False
Process-Process-9 terminate,alive=False
Process-Process-10 ,alive=False
Process-Process-10 terminate,alive=False
Process-Process-11 ,alive=False
Process-Process-11 terminate,alive=False
Process-Process-12 ,alive=False
Process-Process-12 terminate,alive=False
Process-Process-13 ,alive=False
Process-Process-13 terminate,alive=False
Process-Process-14 ,alive=False
Process-Process-14 terminate,alive=False
Process-Process-15 ,alive=False
Process-Process-15 terminate,alive=False
Process-Process-16 ,alive=False
Process-Process-16 terminate,alive=False
Process-Process-17 ,alive=False
Process-Process-17 terminate,alive=False
Process-Process-18 ,alive=False
Process-Process-18 terminate,alive=False
Process-Process-19 ,alive=False
Process-Process-19 terminate,alive=False

标签:Process,Multiprocess,False,start,Python,alive,并发,time,process
From: https://www.cnblogs.com/aksoam/p/18225742

相关文章

  • 淘宝API接口大全,实时数据接口且支持高并发请求不限制
    前言在开发测试阶段,或者是在写Demo的时候,难免会用到一些测试数据,有时苦于没有可用的接口,需要自己动手去写,但是这样大大降低了效率,前期我也找了一些封装好的接口,这篇文章整理一下,以下接口完全免费测试,返回格式全是JSON,所有接口均可无限制使用,有需要的小伙伴可以进来看看。 ......
  • 【计算机毕业设计】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模
    谷物识别系统,本系统使用Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经算法网络模型,通过对11种谷物图片数据集('大米','小米','燕麦','玉米渣','红豆','绿豆','花生仁','荞麦','黄豆','黑米','黑豆')进行训练......
  • 为什么 python 会出现这种行为?
    我试图在Python中将数字动态追加到2D数组中。temp=[]arr=[tempforiinrange(2)]Arr[0].append("erg;erg)arr[0].append("ergse")print(arr)我得到的输出结果是......
  • 基于python美食网站的设计与实现论文
    目录摘要IAbstractII第1章绪论11.1项目研究的背景11.2开发目的和意义11.3国内外研究现状1第2章系统开发工具32.1Python编程语言32.2B/S模式32.3MySQL数据库42.4Django框架介绍42.5Vue开发技术52.6JavaScript简介5第3章系统分析73.......
  • 基于Python高校成绩分析的设计与实现论文
    目录1绪论11.1开发背景11.2国内外研究现状和发展趋势综述11.3开发设计的意义及研究方向12系统开发技术32.1Python可视化技术32.2Django框架32.3IDEA介绍32.4B/S架构42.5MySQL数据库介绍43系统分析53.1整体分析53.2功能需求分析53.3系......
  • python参数传递与Java参数传递的对比
    目录一、本文简介二、参数传递的类型三、python中参数传递的类型3.1可变对象与不可变对象3.2对象引用传递和引用传递的区别3.3如何理解python中列表的"+"操作和append操作的区别四、Java中参数传递的类型附录一、本文简介python参数传递的类型是“对象引用传递”......
  • Python While 循环语句
    Python编程中while语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为:```while判断条件(condition):  执行语句(statements)……```执行语句可以是单个语句或语句块。判断条件可以是任何表达式,任何非零、或非空(null)的值......
  • Python 运算符
    相关学习资料什么是运算符?本章节主要说明Python的运算符。举个简单的例子 4+5=9 。例子中,4 和 5 被称为操作数,+ 称为运算符。Python语言支持以下类型的运算符:算术运算符比较(关系)运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级接下来让......
  • JUC并发编程第六章——volatile与JMM
    1被volatile修饰的变量有两大特点特点:可见性有序性:有排序要求,有时需要禁重排内存语义:当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内存中当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,重新回到主内存中读取最新共享......
  • 在Python中使用生成器:高效处理大型数据集
    生成器是Python中强大且高效的概念,它能够帮助我们处理大型数据集,同时节省内存空间。本文将深入讨论生成器的概念、用法和优势,通过代码案例帮助读者更容易理解和掌握这一高级知识点。生成器的介绍生成器是一种特殊的迭代器,它能够在需要时生成值,而无需在内存中同时存储所有......