首页 > 编程问答 >我想使用 torch DataLoader 并使用生产者/消费者模式,但它卡住了

我想使用 torch DataLoader 并使用生产者/消费者模式,但它卡住了

时间:2024-07-24 13:48:33浏览次数:13  
标签:python python-3.x pytorch pytorch-dataloader

我想更改 torch DataLoader,并在其中使用消费者/生产者模式。

我有一个队列,一个线程将文件放入其中,这些项目由框架使用 __getitem__ 使用。

这是我的代码:

import glob
import time
from torch.utils.data import DataLoader, Dataset
import threading
import queue




class CustomDataset(Dataset):
    size = 25
    def __init__(self):
        self.voices_path = "/home/hatef/mmm/data/voice/"
        file_list = glob.glob(self.voices_path + "*")
        self.data = []
        for f in file_list:
            self.data.append(f)
        self.q = queue.Queue(CustomDataset.size)

    def fill_queue(self):
        dataz = self.data
        it = 0
        while it < len(dataz):
            path = dataz[it]
            if not self.q.full():
                with open(path,"rb") as f:
                    self.q.put(f.read())
                    it += 1
            else:
                print("queue size: " + str(self.q.qsize()))
                time.sleep(2)

    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, _):
        print("before get item")
        item = self.q.get()
        self.q.task_done()
        return [item, 1]
 

    
params = {'batch_size': 16,
          'shuffle': True,
          'num_workers': 4}


epoch = 100


dataset = CustomDataset()
training_generator = DataLoader(dataset, **params)

producer = threading.Thread(target=dataset.fill_queue, daemon=True)
producer.start()

start_time = time.time()

for i in range(epoch):
    for f in training_generator:
        print(f) 
        print("............")
    print(f"**********************************run epoch***************************************: {i}")
# time.sleep(10)
end_time = time.time()

execution_time = end_time - start_time

print(f"Execution time: {execution_time} seconds")


   

__getitem__ 我的代码永远不会取得进展。问题是什么?


代码中的问题在于, __getitem__ 方法中的 self.q.get() 调用会在队列为空时阻塞。这意味着,当工作线程尝试从队列中获取项目时,如果队列为空,它们就会被阻塞,直到有项目可用为止。由于没有在主线程中将任何项目放入队列,因此工作线程会无限期地阻塞,从而导致死锁。

以下是如何使用生产者/消费者模式修复代码的方法:

  1. 在单独的线程中启动生产者 :已经使用 threading.Thread 在单独的线程中启动了生产者,这是正确的。

  2. 使用 q.get(block=True, timeout=None) :修改 __getitem__ 方法,以便它在从队列中获取项目时使用 block=True timeout 参数。这将确保工作线程在队列为空时不会无限期地阻塞。

  3. fill_queue 方法中处理异常 :当队列已满时, q.put(item) 调用会引发 queue.Full 异常。需要在 fill_queue 方法中处理此异常,例如,通过休眠一小段时间,然后重试。

  4. 在主线程中加入生产者线程 :在主线程中使用 producer.join() 方法等待生产者线程完成。

以下是更新后的代码:

import glob
import time
from torch.utils.data import DataLoader, Dataset
import threading
import queue

class CustomDataset(Dataset):
    size = 25

    def __init__(self):
        self.voices_path = "/home/hatef/mmm/data/voice/"
        file_list = glob.glob(self.voices_path + "*")
        self.data = file_list  # 不需要将文件内容存储在内存中
        self.q = queue.Queue(CustomDataset.size)

    def fill_queue(self):
        for path in self.data:
            try:
                with open(path, "rb") as f:
                    self.q.put(f.read(), block=True, timeout=5)  # 设置超时时间
            except queue.Full:
                print("队列已满,稍后再试...")
                time.sleep(1)
        print("生产者已完成")

    def __len__(self):
        return len(self.data)

    def __getitem__(self, _):
        item = self.q.get(block=True, timeout=5)  # 设置超时时间
        self.q.task_done()
        return [item, 1]

params = {'batch_size': 16,
          'shuffle': True,
          'num_workers': 4}

epoch = 100

dataset = CustomDataset()
training_generator = DataLoader(dataset, **params)

producer = threading.Thread(target=dataset.fill_queue, daemon=True)
producer.start()

start_time = time.time()

for i in range(epoch):
    for f in training_generator:
        print(f)
        print("............")
    print(f"**********************************运行时期***************************************: {i}")
# time.sleep(10)

producer.join()  # 等待生产者线程完成

end_time = time.time()

execution_time = end_time - start_time

print(f"执行时间: {execution_time} 秒")

这些更改将确保:

  • 生产者线程在将所有数据放入队列后完成。
  • 工作线程在从队列中获取项目时不会无限期地阻塞。
  • 主线程在生产者线程完成后结束。

标签:python,python-3.x,pytorch,pytorch-dataloader
From: 78784246

相关文章

  • Python 类型提示:自引用类型检查
    我认为静态类型确实会让我在Python中的生活更轻松,考虑到我通常使用C语言工作。我创建了一个像这样的类:classnode(object):"""properties,constructor,etc."""defadd_outneighbor(self,neighbor:node)->None:"""d......
  • Python用shp文件裁剪多个遥感影像的方法
      本文介绍基于Python中ArcPy模块,基于矢量数据范围,对大量栅格遥感影像加以批量裁剪掩膜的方法。  首先,话不多说,本文所需要的代码如下所示。#-*-coding:utf-8-*-"""CreatedonTueDec1320:07:482022@author:fkxxgis"""importarcpyfromarcpy.saimport*......
  • 以编程方式删除 Python 源中的类型提示
    我有一些为Python3.5编写的源代码,我想使其在Python3.4下可执行。我使用的3.5中唯一在3.4中不可用的功能是类型提示,因此我想编写一个脚本来完全删除这些功能。乍一看这似乎很容易,我决定编写一些正则表达式这样做,但后来我想到了一些边缘情况,我不确定如何解决像这样的......
  • Python 类型暗示​​一个充满 myclass 对象的双端队列
    使用Python3.6或更高版本,我想输入提示一个返回MyClass对象的函数myfunc我如何提示myqueue是一个deque|||充满MyClass对象?objects?fromcollectionsimportdequeglobal_queue=deque()classMyClass:passdefmyfunc(m......
  • python之名称空间和作用域(关键字:global和nonlocal的使用)
    文章目录前言1、名称空间和作用域1.1引言1.2名称空间1.2.1内置名称空间1.2.2全局名称空间1.2.3局部名称空间1.2.4名称空间的产生和销毁顺序1.3作用域1.3.1全局作用域1.3.2局部作用域1.3.3名字的查找顺序1.4关键字:global1.5关键字:nonlocal前言本篇文章......
  • 用于 isinstance() 检查的 dict_keys 的显式 python3 类型是什么?
    在Python3中,我应该使用什么类型来检查字典键是否属于它?>>>d={1:2}>>>type(d.keys())<class'dict_keys'>所以我很自然地尝试了这个:>>>isinstance(d.keys(),dict_keys)Traceback(mostrecentcalllast):File"<stdin>",......
  • 初学Python时需要认识清楚的几个概念:对象、函数、圆括号给、点取、方括号取
    这是我在自学Python的过程中自己挑选和提炼出来的几个重要的概念,之所以特意介绍这些概念,其中包含了我自己的思维方式和我对Python设计理念的认识,有其独特性和局限性。我希望这篇文章能够给喜爱Python的朋友们带来一些启发。1、对象(Object)对象是Python编程的基本单元。就像音是......
  • 如何接受文件或路径作为python中方法的参数
    我正在尝试编写一个方法,该方法将接受打开的文件myFile=open("myFile.txt")obj.writeTo(myFile)myFile.close()或带有路径的字符串obj.writeTo("myFile.txt")该方法的实现如下:defwriteTo(self,hessianFile):ifisinstance(hessianFile,file):pr......
  • Python,“pathlib.Path.open()”方法和内置函数“open()”不返回“typing.IO”的实例
    我读过一些其他答案,它们似乎与现实生活中发生的事情相矛盾。尝试以下操作:fromtypingimportIOfrompathlibimportPathexample_path=Path(r"D:\Example.txt")withexample_path.open("r")asf:print(isinstance(f,IO))withopen(example_path)a......
  • 【Dison夏令营 Day 28】用 Python 创建恐龙游戏
    谁没有玩过谷歌著名的“恐龙游戏”?也许每个人都玩过这个游戏。今天,在这篇文章中,我们将帮助你用Python开发一个恐龙游戏。本教程将深入讲解每一行代码,并提供参考资料。我们将尽力让读者详细、透彻地理解这个项目。Python版恐龙游戏的任务记录包括图片文档和Python资料......