Python使用multiprocessing实现多进程

        大家好,当我们工作中涉及到处理大量数据、并行计算或并发任务时,Python的multiprocessing模块是一个强大而实用的工具。通过它,我们可以轻松地利用多核处理器的优势,将任务分配给多个进程并同时执行,从而提高程序的性能和效率。在本文中,我们将探索如何使用multiprocessing模块实现多进程编程。将介绍进程池的概念和用法,以及如何使用它来管理和调度多个进程。我们还将讨论并发任务的处理、进程间通信和结果获取等关键问题,希望能给大家的工作带来一些帮助。

一、介绍

        Python多进程是一种并行编程模型,允许在Python程序中同时执行多个进程。每个进程都拥有自己的独立内存空间和执行环境,可以并行地执行任务,从而提高程序的性能和效率。

优点:

  • 并行处理:多进程可以同时执行多个任务,充分利用多核处理器的能力,实现并行处理。这可以显著提高程序的性能和效率,特别是在处理密集型任务或需要大量计算的场景中。

  • 独立性:每个进程都有自己的独立地址空间和执行环境,进程之间互不干扰。这意味着每个进程都可以独立地执行任务,不会受到其他进程的影响。这种独立性使得多进程编程更加健壮和可靠。

  • 内存隔离:由于每个进程都拥有自己的地址空间,多进程之间的数据是相互隔离的。这意味着不同进程之间的变量和数据不会相互影响,减少了数据共享和同步的复杂性。

  • 故障隔离:如果一个进程崩溃或出现错误,不会影响其他进程的执行。每个进程是独立的实体,一个进程的故障不会对整个程序产生致命影响,提高了程序的稳定性和容错性。

  • 可移植性:多进程编程可以在不同的操作系统上运行,因为进程是操作系统提供的基本概念。这使得多进程编程具有很好的可移植性,可以在不同的平台上部署和运行。

缺点:

  • 资源消耗:每个进程都需要独立的内存空间和系统资源,包括打开的文件、网络连接等。多进程编程可能会增加系统的资源消耗,尤其是在创建大量进程时。

  • 上下文切换开销:在多进程编程中,进程之间的切换需要保存和恢复进程的执行环境,这涉及到上下文切换的开销。频繁的进程切换可能会导致额外的开销,影响程序的性能。

  • 数据共享与同步:由于多进程之间的数据是相互隔离的,需要通过特定的机制进行数据共享和同步。这可能涉及到进程间通信(IPC)的复杂性,如队列、管道、共享内存等。正确处理数据共享和同步是多进程编程中的挑战之一。

  • 编程复杂性:相比于单线程或多线程编程,多进程编程可能更加复杂。需要考虑进程的创建和管理、进程间通信、数据共享和同步等问题。编写和调试多进程程序可能需要更多的工作和经验。

进程与线程:

  • 在讨论多进程之前,需要明确进程(Process)和线程(Thread)的概念。
  • 进程是计算机中正在运行的程序的实例。每个进程都有自己的地址空间、数据栈和控制信息,可以独立执行任务。
  • 线程是进程中的一个执行单元,可以看作是轻量级的进程。多个线程共享同一进程的资源,包括内存空间、文件描述符等。

        多进程编程在并行处理和资源隔离方面具有明显的优势,但也涉及到资源消耗、上下文切换开销、数据共享和同步等问题。在实际应用中,开发者应权衡利弊,根据具体场景选择适合的编程模型和工具。

二、创建进程

        在Python中,可以使用multiprocessing模块来创建和管理进程。该模块提供了丰富的类和函数,用于创建、启动和管理进程。

1、导入multiprocessing模块

在使用multiprocessing模块之前,需要先导入它:

import multiprocessing

2、创建进程

        可以使用multiprocessing.Process类来创建进程对象。需要传入一个目标函数作为进程的执行逻辑。可以通过继承multiprocessing.Process类来自定义进程类。

import multiprocessing

def worker():
    # 进程执行的逻辑

if __name__ == '__main__':
    process = multiprocessing.Process(target=worker)

        在上面的示例中,worker函数是进程的执行逻辑。进程对象创建后,可以通过设置参数、调用方法等来配置进程。

3、启动进程

通过调用进程对象的start()方法,可以启动进程。进程会在后台开始执行。

process.start()

4、进程的状态

进程对象提供了一些方法来获取和管理进程的状态:

  • is_alive():检查进程是否正在运行。
  • join([timeout]):等待进程结束。可选参数timeout指定等待的最长时间。
if process.is_alive():
    print("进程正在运行")

process.join()

5、进程的终止

进程可以通过调用进程对象的terminate()方法来终止。这会立即停止进程的执行。

process.terminate()

二、进程间通信

        进程间通信(Inter-Process Communication,IPC)是指不同进程之间进行数据交换和共享信息的机制。在多进程编程中,进程之间通常需要进行数据传输、共享状态或进行同步操作。Python提供了多种进程间通信的机制,包括队列(Queue)、管道(Pipe)、共享内存(Value、Array)等。

1、队列(Queue)

        队列是一种常用的进程间通信方式,通过队列可以实现进程之间的数据传输。Python的multiprocessing模块提供了Queue类来实现多进程之间的队列通信。进程可以通过put()方法将数据放入队列,其他进程则可以通过get()方法从队列中获取数据。

from multiprocessing import Queue

# 创建队列
queue = Queue()

# 进程1放入数据
queue.put(data)

# 进程2获取数据
data = queue.get()

2、管道(Pipe)

        管道是另一种常用的进程间通信方式,通过管道可以实现进程之间的双向通信。Python的multiprocessing模块提供了Pipe类来创建管道对象。Pipe()方法返回两个连接的管道端,一个用于发送数据,另一个用于接收数据。

from multiprocessing import Pipe

# 创建管道
conn1, conn2 = Pipe()

# 进程1发送数据
conn1.send(data)

# 进程2接收数据
data = conn2.recv()

3、共享内存(Value、Array)

        共享内存是一种在多进程之间共享数据的高效方式。Python的multiprocessing模块提供了ValueArray类来实现进程间共享数据。Value用于共享单个值,而Array用于共享数组。

from multiprocessing import Value, Array

# 创建共享值
shared_value = Value('i', 0)

# 创建共享数组
shared_array = Array('i', [1, 2, 3, 4, 5])

        在创建共享值和共享数组时,需要指定数据类型(如整数、浮点数)和初始值。进程可以通过读写共享值和共享数组来进行进程间的数据共享。

4、信号量(Semaphore)

        信号量是一种用于控制对共享资源的访问的机制。在多进程编程中,信号量可以用于限制同时访问某个共享资源的进程数量。

from multiprocessing import Semaphore, Process
import time

def worker(semaphore, name):
    semaphore.acquire()
    print("Worker", name, "acquired semaphore")
    time.sleep(2)
    print("Worker", name, "released semaphore")
    semaphore.release()

semaphore = Semaphore(2)

processes = []
for i in range(5):
    p = Process(target=worker, args=(semaphore, i))
    processes.append(p)
    p.start()

for p in processes:
    p.join()

        在上述例子中,创建了一个信号量,初始值为2。然后创建了5个进程,每个进程在执行前会尝试获取信号量,如果信号量的值大于0,则成功获取;否则,进程将被阻塞,直到有进程释放信号量。每个进程获取信号量后,会执行一段任务,并在执行完后释放信号量。

5、事件(Event)

        事件是一种用于多进程间通信的同步机制,它允许一个或多个进程等待某个事件的发生,然后再继续执行。

from multiprocessing import Event, Process
import time

def worker(event, name):
    print("Worker", name, "waiting for event")
    event.wait()
    print("Worker", name, "received event")
    time.sleep(2)
    print("Worker", name, "completed task")

event = Event()

processes = []
for i in range(3):
    p = Process(target=worker, args=(event, i))
    processes.append(p)
    p.start()

time.sleep(3)
event.set()

for p in processes:
    p.join()

        在上述例子中,创建了一个事件。然后创建了3个进程,每个进程在执行前会等待事件的发生,即调用event.wait()方法。主进程休眠3秒后,设置事件的状态为已发生,即调用event.set()方法。此时,所有等待事件的进程将被唤醒,并继续执行任务。

6、条件变量(Condition)

条件变量是一种用于多进程间协调和同步的机制,它可以用于控制多个进程之间的执行顺序。

from multiprocessing import Condition, Process
import time

def consumer(condition):
    with condition:
        print("Consumer is waiting")
        condition.wait()
        print("Consumer is consuming the product")

def producer(condition):
    with condition:
        time.sleep(2)
        print("Producer is producing the product")
        condition.notify()

condition = Condition()

consumer_process = Process(target=consumer, args=(condition,))
producer_process = Process(target=producer, args=(condition,))

consumer_process.start()
producer_process.start()

consumer_process.join()
producer_process.join()

        在上述例子中,创建了一个条件变量。然后创建了一个消费者进程和一个生产者进程。消费者进程在执行前等待条件的满足,即调用condition.wait()方法。生产者进程休眠2秒后,生成产品并通过condition.notify()方法通知消费者。消费者收到通知后继续执行任务。

三、进程间同步

        进程间同步是确保多个进程按照特定顺序执行或在共享资源上进行互斥访问的一种机制。进程间同步的目的是避免竞态条件(race condition)和数据不一致的问题。Python提供了多种机制来实现进程间的同步,包括锁(Lock)、信号量(Semaphore)、事件(Event)、条件变量(Condition)等。

1、锁(Lock)

        锁是一种最基本的同步机制,用于保护共享资源的互斥访问,确保在任意时刻只有一个进程可以访问共享资源。在Python中,可以使用multiprocessing模块的Lock类来实现锁。

from multiprocessing import Lock, Process

lock = Lock()

def worker(lock, data):
    lock.acquire()
    try:
        # 对共享资源进行操作
        pass
    finally:
        lock.release()

processes = []
for i in range(5):
    p = Process(target=worker, args=(lock, i))
    processes.append(p)
    p.start()

for p in processes:
    p.join()

        在上述例子中,每个进程在访问共享资源之前会先获取锁,然后在完成操作后释放锁。这样可以确保在同一时刻只有一个进程能够访问共享资源,避免数据竞争问题。

2、信号量(Semaphore)

        信号量是一种更为灵活的同步机制,它允许多个进程同时访问某个资源,但限制同时访问的进程数量。在Python中,可以使用multiprocessing模块的Semaphore类来实现信号量。

from multiprocessing import Semaphore, Process

semaphore = Semaphore(2)

def worker(semaphore, data):
    semaphore.acquire()
    try:
        # 对共享资源进行操作
        pass
    finally:
        semaphore.release()

processes = []
for i in range(5):
    p = Process(target=worker, args=(semaphore, i))
    processes.append(p)
    p.start()

for p in processes:
    p.join()

        在上述例子中,创建了一个初始值为2的信号量。每个进程在访问共享资源之前会尝试获取信号量,只有当信号量的值大于0时才能获取成功,否则进程将被阻塞。获取成功后,进程可以进行操作,并在完成后释放信号量。

3、事件(Event)

        事件是一种同步机制,用于实现进程之间的等待和通知机制。一个进程可以等待事件的发生,而另一个进程可以触发事件的发生。在Python中,可以使用multiprocessing模块的Event类来实现事件。

from multiprocessing import Event, Process

event = Event()

def worker(event, data):
    event.wait()
    # 执行任务

processes = []
for i in range(5):
    p = Process(target=worker, args=(event, i))
    processes.append(p)
    p.start()

# 触发事件的发生
event.set()

for p in processes:
    p.join()

        在上述例子中,多个进程在执行任务前会等待事件的发生,即调用event.wait()方法。主进程通过调用event.set()方法来触发事件的发生,进而唤醒等待的进程继续执行。

4、条件变量(Condition)

        条件变量是一种复杂的同步机制,它允许进程按照特定的条件等待和通知。在Python中,可以使用multiprocessing模块的Condition类来实现条件变量。

from multiprocessing import Condition, Process

condition = Condition()

def consumer(condition(续):

def consumer(condition, data):
    with condition:
        while True:
            # 检查条件是否满足
            while not condition_is_met():
                condition.wait()
            # 从共享资源中消费数据

def producer(condition, data):
    with condition:
        # 生成数据并更新共享资源
        condition.notify_all()

processes = []
for i in range(5):
    p = Process(target=consumer, args=(condition, i))
    processes.append(p)
    p.start()

producer_process = Process(target=producer, args=(condition, data))
producer_process.start()

for p in processes:
    p.join()
producer_process.join()

        在上述例子中,消费者进程在执行任务前会检查条件是否满足,如果条件不满足,则调用condition.wait()方法等待条件的满足。生产者进程生成数据并更新共享资源后,调用condition.notify_all()方法通知所有等待的消费者进程条件已满足。被唤醒的消费者进程会重新检查条件并执行任务。

四、进程池

        进程池是一种用于管理和调度多个进程的机制,它可以有效地处理并行任务和提高程序的性能。进程池在Python中通常使用multiprocessing模块提供的Pool类来实现。

进程池的工作原理如下:

  1. 创建进程池时,会启动指定数量的进程,并将它们放入池中。
  2. 池中的进程会等待主进程提交任务。
  3. 主进程通过提交任务给进程池,将任务分配给空闲的进程。
  4. 进程池中的进程执行任务,并将结果返回给主进程。
  5. 主进程获取任务的结果,继续执行其他操作。
  6. 当所有任务完成后,主进程关闭进程池。

1、创建进程池

        要使用进程池,首先需要创建一个Pool对象,可以指定池中的进程数量。通常,可以使用multiprocessing.cpu_count()函数来获取当前系统的CPU核心数,然后根据需要来指定进程池的大小。

from multiprocessing import Pool, cpu_count

pool = Pool(processes=cpu_count())

在上述例子中,创建了一个进程池,进程数量与系统的CPU核心数相同。

2、提交任务

一旦创建了进程池,就可以使用apply()map()imap()方法来提交任务给进程池。

  • apply()方法用于提交单个任务,并等待任务完成后返回结果。
    result = pool.apply(function, args=(arg1, arg2))
  • map()方法用于提交多个任务,并按照任务提交的顺序返回结果列表。
    results = pool.map(function, iterable)
  • imap()方法也用于提交多个任务,但可以通过迭代器逐个获取结果,而不需要等待所有任务完成。
    results = pool.imap(function, iterable)

        在上述例子中,function表示要执行的函数,args是函数的参数,iterable是一个可迭代对象,可以是列表、元组等。

3、获取结果

        对于apply()方法,调用后会阻塞主进程,直到任务完成并返回结果。对于map()方法,调用后会等待所有任务完成,并按照任务提交的顺序返回结果列表。对于imap()方法,可以通过迭代器逐个获取结果。

for result in results:
    print(result)

在上述例子中,使用for循环逐个获取结果并进行处理。

4、关闭进程池

在所有任务完成后,需要显式地关闭进程池,以释放资源。

pool.close()
pool.join()

        调用close()方法后,进程池将不再接受新的任务。调用join()方法会阻塞主进程,直到所有任务都已完成。

5、使用进程池的示例

from multiprocessing import Pool

# 定义一个任务函数
def square(x):
    return x ** 2

if __name__ == '__main__':
    # 创建进程池
    with Pool(processes=4) as pool:
        # 提交任务给进程池
        results = pool.map(square, range(10))

    # 打印结果
    print(results)

        在上述示例中,首先定义了一个任务函数square,它接受一个数值作为参数,并返回该数值的平方。

        在if __name__ == '__main__':中,创建了一个进程池,指定进程数量为4。使用with语句可以确保进程池在使用完毕后被正确关闭。

        然后,通过pool.map(square, range(10))将任务提交给进程池。map()方法会将任务函数square和一个可迭代对象range(10)作为参数,它会将可迭代对象中的每个元素依次传递给任务函数进行处理,并返回结果列表。最后,打印结果列表,即每个数值的平方。

        需要注意的是,在使用进程池时,需要将主程序代码放在if __name__ == '__main__':中,以确保在子进程中不会重复执行主程序的代码。

        以下是一个更加复杂的多进程示例,展示了如何使用进程池处理多个任务,并在任务完成时获取结果。

import time
from multiprocessing import Pool

# 定义一个任务函数
def process_data(data):
    # 模拟耗时操作
    time.sleep(1)
    # 返回处理结果
    return data.upper()

if __name__ == '__main__':
    # 创建进程池
    with Pool(processes=3) as pool:
        # 准备数据
        data_list = ['apple', 'banana', 'cherry', 'date', 'elderberry']

        # 提交任务给进程池
        results = [pool.apply_async(process_data, args=(data,)) for data in data_list]

        # 等待所有任务完成并获取结果
        final_results = [result.get() for result in results]

    # 打印结果
    for result in final_results:
        print(result)

        在上述示例中,除了使用进程池的map()方法提交任务之外,还使用了apply_async()方法来异步提交任务,并通过get()方法获取任务的结果。

        在if __name__ == '__main__':中,创建了一个进程池,指定进程数量为3。使用with语句可以确保进程池在使用完毕后被正确关闭。然后,准备了一个数据列表data_list,其中包含了需要处理的数据。

        通过列表推导式,使用pool.apply_async(process_data, args=(data,))将任务异步提交给进程池。apply_async()方法会将任务函数process_data和数据data作为参数,返回一个AsyncResult对象,表示异步任务的结果。将这些对象存储在results列表中。

        接下来,使用列表推导式,通过result.get()方法等待所有任务完成并获取结果,将结果存储在final_results列表中。最后,使用for循环遍历final_results列表,并打印每个任务的处理结果。

        进程池的优点是可以自动管理和调度多个进程,充分利用系统资源,提高程序的并行执行能力。通过合理设置进程池的大小,可以在不过度消耗系统资源的情况下,实现最佳的并发效果。但需要注意的是,进程池适用于那些需要并行执行的任务,而不适用于IO密集型任务,因为进程池中的进程是通过复制主进程来创建的,而IO密集型任务更适合使用线程池来实现并发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/639881.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTFHUB技能树——SSRF(二)

目录 上传文件 ​FastCGI协议 Redis协议 上传文件 题目描述&#xff1a;这次需要上传一个文件到flag.php了.祝你好运 index.php与上题一样&#xff0c;使用POST请求的方法向flag.php传递参数 //flag.php页面源码 <?phperror_reporting(0);if($_SERVER["REMOTE_ADDR&…

“从根到叶:使用决策树导航数据”

目录 一、说明 二、什么是决策树&#xff1f; 三、基本概念&#xff1a; 四、工作原理&#xff1a; 五、分类原理分析 5.1 信息熵&#xff1a; 5.2 信息增益&#xff1a; 5.3 基尼杂质&#xff1a; 5.4 基尼系数和熵的区别&#xff1a; 六、对于回归决策树&#xff1a; 6.1 均方…

OR-Oncology Research 肿瘤学研究

文章目录 一、期刊简介二、征稿信息三、期刊表现四、投稿须知五、投稿咨询 一、期刊简介 Oncology Research以临床前和临床癌症治疗为特色&#xff0c;发表了高质量的同行评审研究&#xff0c;有助于在分子生物学、细胞生物学、生物化学、生物物理学、遗传学、生物学、内分泌学…

128天的创意之旅:从初心到成就,我的博客创作纪念日回顾

文章目录 &#x1f680;机缘&#xff1a;初心的种子——回望创作之旅的启航&#x1f308;收获&#xff1a;成长的果实——128天创作之旅的宝贵馈赠❤️日常&#xff1a;创作与生活的交织&#x1f44a;成就&#xff1a;代码的艺术&#x1f6b2;憧憬&#xff1a;未来的蓝图 &…

【RabbitMQ】SpringAMQP--消息转换器

SpringAMQP–消息转换器 测试发送Object类型消息 1.声明队列 Configuration public class FanoutConfig {Beanpublic Queue objectQueue(){return new Queue("object.queue");} }运行消费者后&#xff1a; 2.发送消息 RunWith(SpringRunner.class) SpringBootTes…

01.爬虫---初识网络爬虫

01.初识网络爬虫 1.什么是网络爬虫2.网络爬虫的类型3.网络爬虫的工作原理4.网络爬虫的应用场景5.网络爬虫的挑战与应对策略6.爬虫的合法性总结 1.什么是网络爬虫 网络爬虫&#xff0c;亦称网络蜘蛛或网络机器人&#xff0c;是一种能够自动地、系统地浏览和收集互联网上信息的程…

物联网应用开发--STM32与机智云通信(ESP8266 Wi-Fi+手机APP+LED+蜂鸣器+SHT20温湿度传感器)

实现目标 1、熟悉机智云平台&#xff0c;会下载APP 2、熟悉新云平台创建产品&#xff0c;项目虚拟调试 3、掌握云平台生成MCU代码&#xff0c;并移植。机智云透传固件的下载 4、具体目标&#xff1a;&#xff08;1&#xff09;注册机智云平台&#xff1b;&#xff08;2&…

数据结构~~二叉树-堆

目录 一、基本概念 树的概念 二叉树-堆的概念 二、堆的结构 三、堆排序 向上调整建堆 向下调整建堆 四、TOP-K 五、完整代码 六、总结 一、基本概念 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关…

在ubuntu中查询与某脚本或某设备相关的进程,ps,pgrep,lsof,fuser,pstree,htop命令的使用指南

一、查询与脚本有关的进程 1. 用ps命令 在 Ubuntu 系统中&#xff0c;如果你想查询与特定 Python 脚本 abc.py 相关的线程&#xff0c;你可以使用 ps 命令和 grep 命令结合来查找。ps 命令用于显示当前运行的进程状态&#xff0c;而 grep 命令可以帮助你过滤出包含指定字符串…

(六)DockerCompose安装与配置

DockerCompose简介 Compose 项目是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的快速编排。使用前面介绍的Dockerfile我们很容易定义一个单独的应用容器。然而在日常开发工作中&#xff0c;经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现…

Docker Desktop安装和如何在WSL2中使用Docker

最近在使用WSL的过程中&#xff0c;想使用docker遇到了一些问题&#xff0c;在WSL中安装Linux版本的docker&#xff0c;启动镜像之后不能从Windows机器的端口映射出来&#xff0c;查了一圈之后&#xff0c;发现应该使用Docker Desktop软件&#xff0c;下面是安装和使用的方式 …

error1310 写入文件时发生错误,请确认您是否有访问权限 也可能出现error 1304 :写入文件时出错

一般错误提示如下 error1310 Error writing to file 错误 1310 &#xff1a;写入文件时出错&#xff1a;请确认您有权访问该目录&#xff0c; error1304 Error writing to file 错误 1304 &#xff1a;写入文件时出错&#xff1a;请确认您有权访问该目录 1.首先我们退出所…

揭秘齿轮加工工艺的选用原则:精准打造高效传动的秘密武器

在机械制造领域&#xff0c;齿轮作为传动系统中的重要组成部分&#xff0c;其加工工艺的选择至关重要。不同的齿轮加工工艺会影响齿轮的精度、耐用性和效率。本文将通过递进式结构&#xff0c;深入探讨齿轮加工工艺的选用原则&#xff0c;带您了解如何精准打造高效传动的秘密武…

SpringBoot3.x + JDK21 整合 Mybatis-Plus

前言 SpringBoot3.0 开始最低要求 Java 17&#xff0c;虽然目前最新的版本为 JDK22&#xff0c;但是在官网上看到 JDK23 在今年9月又要发布了&#xff0c;感觉这 JDK 也有点太过于给力了 所以我们选择用目前的 LTS 版本 JDK21 就好了&#xff0c;不用追求最新的 springboot 版…

DOM【事件、操作节点、DOM案例】--学习JavaEE的day49

day49 JS核心技术 DOM 继day48 事件 键盘事件 监听器&#xff1a;onkeydown、onkeypress、onkeyup <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><input type"text&q…

网站工作原理

web发展史 1.0时代不可修改 2.0可修改&#xff0c;比如发微博 有以下问题&#xff1a; 课程2&#xff1a; 静态页面 html 动态页面 php 经过服务端的语言解释器&#xff0c;解析成html文件&#xff0c;剩下的就和静态流程一样 后面三个是web服务器&#xff0c;语言解释器&…

恶劣天候鲁棒三维目标检测论文整理

恶劣天候鲁棒三维目标检测论文整理 Sunshine to Rainstorm: Cross-Weather Knowledge Distillation for Robust 3D Object DetectionRobo3D: Towards Robust and Reliable 3D Perception against CorruptionsLossDistillNet: 3D Object Detection in Point Cloud Under Harsh W…

Android Low Storage机制之DeviceStorageMonitorService

一、Android 版本 Android 13 二、low storage简介(DeviceStorageMonitorService) 设备存储监视器服务是一个模块&#xff0c;主要用来&#xff1a; 1.监视设备存储&#xff08;“/ data”&#xff09;。 2.每60秒扫描一次免费存储空间(谷歌默认值) 3.当设备的存储空间不足…

prometheusgrafananode_export搭建监控平台

一、环境要求 1、docker安装docker环境 2、docker安装prometheus 3、docker安装grafana 4、node-exportor(安装在被测服务器上) 5、我的服务器是Ubuntu 二、docker 安装prometheus 1、下载Prometheus镜像 docker pull prom/prometheus 2、检查端口是否被占用 安装netstat命…

Vitis HLS 学习笔记--抽象并行编程模型-控制驱动与数据驱动

目录 1. 简介 2. Takeaways 3. Data-driven Task-level Parallelism 3.1 simple_data_driven 示例 3.2 分析 hls::task 类 3.3 分析通道(Channel) 3.4 注意死锁 4. Control-driven Task-level Parallelism 4.1 理解控制驱动的 TLP 4.2 simple_control_driven 示例 4…