# 数据加载-【too many open files】错误

**1. 使用GeneratorDataset加载自定义数据集**

会根据num\_parallel\_workers来启动多线程或多线程来加载数据集，每个进程或者线程中都会尝试去打开数据集文件。

Linux一般默认允许同时打开的文件数为1024，当并发度过高 （num\_parallel\_workers）并且数据集文件较多，可能会导致出现 OSERROR: \[Errno 24\] Too many open files。

此时可以在shell环境上执行ulimit -n 65535来调整同时打开文件的阈值。

另外对Dataset对象进行“非常规”的操作，也有可能导致 Too many open files 错误。

```
  1 import numpy as np
  2 import mindspore.dataset as ds
  3 import argparse
  4 from mindspore import context
  5 from datasets.online_adaptation_dataset import OnlineAdaptationDataset, OnlineAdaptationDatasetStorage
  6
  7 class MyAccessible:
  8     def __init__(self):
  9         self._data = np.random.sample((10, 2))
 10         self._label = np.random.sample((10, 1))
 11
 12     def __getitem__(self, index):
 13         return self._data[index], self._label[index]
 14
 15     def __len__(self):
 16         return len(self._data)
 17
 18 class MyData:
 19     def __init__(self, data):
 20         self.data = data
 21
 22     def __getitem__(self, index):
 23         return self.data.__getitem__(index)
 24
 25 if __name__ == '__main__':
 26     parser = argparse.ArgumentParser(description='MindSpore LeNet Example')
 27     parser.add_argument('--device_target', type=str, default="Ascend", choices=['Ascend', 'GPU', 'CPU'])
 28
 29     args = parser.parse_known_args()[0]
 30     context.set_context(device_id=4, mode=context.PYNATIVE_MODE, device_target=args.device_target)
 31     for i in range(10):
 32         data = MyAccessible()
 33         dataset = ds.GeneratorDataset(source=MyData(data), column_names=["data", "label"],num_parallel_workers=4, shuffle=True)
 34         dataset = dataset.batch(batch_size=2)
 35         import pdb;pdb.set_trace()
 36         datas = iter(dataset)
 37         print(next(datas))
 38         datas = iter(dataset)
```

脚本中第36行使用iter\(\)来创建迭代器对象后，在第37行中使用next\(datas\)读取迭代器中第一个元素，然后在第38行重复使用iter\(\)来创建迭代器。

**2. 原因分析**

1. Mindspore提供了create\_dict\_iterator\(\)和create\_tuple\_iterator\(\)，分别返回dict迭代器和tuple迭代器，不建议直接使用iter\(\)方法来生成迭代器。

create\_dict\_iterator\(\)以及create\_tuple\_iterator\(\)，可以设置num\_epochs参数来控制迭代器的迭代次数，以及output\_numpy参数来控制输出数据类型为numpy.ndarray或者Tensor。

2. 重复调用iter\(\)会重复创建迭代器，而GeneratorDataset加载数据集时默认为多进程加载，每次打开的句柄在主进程停止前得不到释放，导致打开句柄数一直在增长。

**3. 解决方法**

第36行修改为

```
datas=dataset.create_tuple_iterator(num_epochs=1, output_numpy=True)
```

移除第38行

