cannot serialize _io.BufferedReader object python中出现这样的问题

1.出现的这样的问题 cannot serialize _io.BufferedReader object
这篇博文把出现的问题解决
为什么会出现这样的原因
2.本人遇到的问题
现在有两个函数darknet.detect(dataset, event, event_distance, event_count) uwb_rec(result_queue, event, event_distance, event_count),darknet.detect包含进程,uwb_rec是一个协程函数,两个函数都不能用Process和thread函数,而且darknet.detect和uwb_rec两个都是循环函数,一旦进入后就不会再出来。现在我需要在一个main函数中,先后启动这两个程序,并能持续运行。
如果直接对 darknet.detect使用process或者是thread 这种进程函数,会报上面的无法序列化的问题;uwb_rec 是一个协程函数,并不能使用process 和thread 函数进行判断。这里使用的是asyncio.gather函数。
具体的代码如下:

async def main():
    with multiprocessing.Manager() as manager:
        result_queue = manager.Queue()  # Create a Queue for communication
        event = manager.Event()  # Create an Event for signaling
        event_distance = manager.Event()  # Create an Event for signaling distance condition
        event_count = manager.Event()  # Create an Event for signaling count condition

        pts1 = np.loadtxt("pic.txt")
        pts2 = np.loadtxt("uwb.txt")
        pts1 = np.float32(pts1)
        pts2 = np.float32(pts2)
        H,_ = cv2.findHomography(pts1,pts2,cv2.RANSAC,5.0)

        with open('yolov5_config.json', 'r', encoding='utf8') as fp:
            opt = json.load(fp)
            print('[INFO] YOLOv5 Config:', opt)
        darknet = Darknet(opt,result_queue)

        dataset = LoadStreams(darknet.source,img_size=opt["imgsz"],stride=darknet.stride)

        loop = asyncio.get_event_loop()
        task_uwb_rec = asyncio.create_task(uwb_rec(result_queue, event, event_distance, event_count))
        task_darknet = loop.run_in_executor(None, darknet.detect, dataset, event, event_distance, event_count,H)
        await asyncio.gather(task_darknet, task_uwb_rec)

        cv2.destroyAllWindows()


if __name__ == "__main__":
    asyncio.run(main())

上面的代码能正常运行,没有报错

  1. 进程、线程、协程,三者的区别
    进程、线程和协程是计算机编程中用于并发执行任务的三种不同方式,它们有着不同的特点和适用场景。
    (1)进程(Process):
    进程是计算机中的一个独立执行单元,有自己独立的内存空间、代码和数据段。
    进程间通信相对复杂,通信通常需要使用 IPC(Inter-Process Communication)机制。
    进程之间相互独立,一个进程的崩溃通常不会影响其他进程。
    进程启动和销毁的开销相对较大。
    (2)线程(Thread):
    线程是进程中的一个执行单元,多个线程共享同一个进程的资源,包括代码、数据段和打开的文件等。
    线程间通信相对容易,因为它们共享同一地址空间。
    线程之间共享内存,一个线程的崩溃可能导致整个进程的崩溃。
    线程的创建和销毁的开销相对较小。
    (3)协程(Coroutine):
    协程是一种轻量级的线程,是用户级的线程。
    协程通过协作式的方式进行调度,而不是被操作系统内核调度,因此更加轻量。
    协程通信通常通过共享状态进行,而不是像进程和线程那样通过显式的通信机制。
    协程在同一线程中执行,不需要额外的线程切换开销,适用于 I/O 密集型任务。
    总体来说:
    (1)进程和线程是操作系统级别的概念,而协程是在用户空间实现的。
    (2)进程和线程通常是并发执行的,而协程是通过在单一线程中切换执行上下文来实现并发的。
    (3)进程之间的隔离度最高,线程次之,协程是最轻量级的。
    选择使用哪种方式取决于具体的应用场景和需求。通常,进程用于更大的隔离和并发需求,线程用于共享内存的并发需求,而协程则适用于 I/O 密集型任务和高并发场景。

补充:什么是I/O密集型任务和高并发场景
I/O 密集型任务(I/O-bound):
I/O 密集型任务是指应用程序中大部分时间花费在等待 I/O 操作(例如文件读写、网络通信等)完成的任务。
在这种情况下,CPU 大部分时间处于空闲状态,因为它主要在等待数据的读取或写入,而不是进行计算。
优化策略通常包括使用异步 I/O 操作、多线程或多进程,以在等待 I/O 操作的同时执行其他任务。
高并发场景:
高并发场景是指应用程序需要处理大量同时发生的操作或请求,即有很多用户或系统组件同时执行操作。
这可能包括大量的并发用户请求、同时进行的网络通信、消息处理等。
优化策略通常包括使用并发编程模型,例如使用多线程、多进程或协程来同时处理多个任务,以提高系统的吞吐量和响应性能。
在实际应用中,一个应用程序可能同时具有 I/O 密集型和高并发的特点。例如,一个网络服务器可能需要处理大量并发的客户端连接(高并发),而每个连接可能涉及等待数据传输或数据库查询(I/O 密集型)。

import multiprocessing
import threading
import asyncio
import queue

async def coroutine_function(data_queue):
    print("Coroutine is running...")
    # 模拟异步操作
    await asyncio.sleep(2)
    # 将数据放入队列
    data_queue.put("Data from coroutine")
    print("Coroutine is done.")

def process_function(data_queue):
    print("Process is running...")
    # 模拟耗时操作
    time.sleep(2)
    # 将数据放入队列
    data_queue.put("Data from process")
    print("Process is done.")

def thread_function(data_queue):
    print("Thread is running...")
    # 模拟耗时操作
    time.sleep(2)
    # 将数据放入队列
    data_queue.put("Data from thread")
    print("Thread is done.")

async def main():
    print("Main function started.")

    # 创建一个队列用于数据传输
    data_queue = queue.Queue()
    # 进程
    process = multiprocessing.Process(target=process_function, args=(data_queue,))
    process.start()
    # 线程
    thread = threading.Thread(target=thread_function, args=(data_queue,))
    thread.start()
    # 协程
    await asyncio.gather(coroutine_function(data_queue))
    # 等待进程和线程完成
    process.join()
    thread.join()
    # 从队列中获取数据
    data_from_process = data_queue.get()
    data_from_thread = data_queue.get()
    data_from_coroutine = data_queue.get()
    print("Data received from process:", data_from_process)
    print("Data received from thread:", data_from_thread)
    print("Data received from coroutine:", data_from_coroutine)

    print("Main function finished.")

if __name__ == "__main__":
    asyncio.run(main())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值