目录
- 1 项目场景&问题描述:
- 2 原因分析:
- 2.1 问题背景:
- 3 解决方案:
- 3.1 创建存放临时文件的目录
- 3.2 使用该目录
- 3.2.1 设置环境变量 TMPDIR
- 3.2.2 运行时设置(推荐)
- 3.2.3 代码中设置
- 4 总结
1 项目场景&问题描述:
Linux下在加载DataLoader中报错
Testing DataLoader 0: 100%|██████████| 21/21 [00:04<00:00, 5.06it/s]Traceback (most recent call last):
File "/root/miniconda3/envs/pli/lib/python3.8/multiprocessing/util.py", line 300, in _run_finalizers
finalizer()
File "/root/miniconda3/envs/pli/lib/python3.8/multiprocessing/util.py", line 224, in __call__
res = self._callback(*self._args, **self._kwargs)
File "/root/miniconda3/envs/pli/lib/python3.8/multiprocessing/util.py", line 133, in _remove_temp_dir
rmtree(tempdir)
File "/root/miniconda3/envs/pli/lib/python3.8/shutil.py", line 718, in rmtree
_rmtree_safe_fd(fd, path, onerror)
File "/root/miniconda3/envs/pli/lib/python3.8/shutil.py", line 675, in _rmtree_safe_fd
onerror(os.unlink, fullname, sys.exc_info())
File "/root/miniconda3/envs/pli/lib/python3.8/shutil.py", line 673, in _rmtree_safe_fd
os.unlink(entry.name, dir_fd=topfd)
OSError: [Errno 16] Device or resource busy: '.nfs05fc000000a862ca0000099b'
Traceback (most recent call last):
File "/root/miniconda3/envs/pli/lib/python3.8/multiprocessing/util.py", line 300, in _run_finalizers
finalizer()
File "/root/miniconda3/envs/pli/lib/python3.8/multiprocessing/util.py", line 224, in __call__
res = self._callback(*self._args, **self._kwargs)
File "/root/miniconda3/envs/pli/lib/python3.8/multiprocessing/util.py", line 133, in _remove_temp_dir
rmtree(tempdir)
File "/root/miniconda3/envs/pli/lib/python3.8/shutil.py", line 718, in rmtree
_rmtree_safe_fd(fd, path, onerror)
File "/root/miniconda3/envs/pli/lib/python3.8/shutil.py", line 675, in _rmtree_safe_fd
onerror(os.unlink, fullname, sys.exc_info())
File "/root/miniconda3/envs/pli/lib/python3.8/shutil.py", line 673, in _rmtree_safe_fd
os.unlink(entry.name, dir_fd=topfd)
OSError: [Errno 16] Device or resource busy: '.nfs65fc000000a862ca00000999'
2 原因分析:
与在 Linux 系统上使用无状态的文件服务器(如 NFS)时遇到的文件访问和临时文件处理有关。
2.1 问题背景:
当文件被一个进程使用时,Linux 在删除该文件时不会立即从磁盘上删除,而是将其重命名为一个以 .nfs 开头的临时文件(例如 .nfs0000)。这意味着,其他进程在文件被删除时仍然可以继续访问这个文件。
迁移文件时,将整个文件迁移到了文件服务器上,临时文件也存储在了这个无状态的文件服务器上。当一个进程在尝试删除这些临时文件时,由于其他进程仍在使用它们,就会引发 OSError: [Errno 16] Device or resource busy
错误。
3 解决方案:
3.1 创建存放临时文件的目录
mkdir -m 1777 /你要存放的路径/tmp
创建了一个目录,权限设为 1777,意味着任何用户都可以读、写、执行该目录。
3.2 使用该目录
3.2.1 设置环境变量 TMPDIR
可以通过设置环境变量 TMPDIR 来指定临时文件的目录。常见的环境变量包括:
- TMPDIR
- TEMP
- TMP
通过这些环境变量,系统或程序会将临时文件写入你指定的目录。具体设置可以通过在命令行运行以下命令:
export TMPDIR=/路径/tmp
3.2.2 运行时设置(推荐)
或者在启动容器时直接设置这个变量。例如,在运行 PyTorch 的程序时,你可以在命令行中运行:
TMPDIR=/路径/tmp python your_script.py
这样,程序中的临时文件就会被写入到 /路径/tmp。
推荐默认后台运行记录log,记得先创建与main.py同级目录的log文件夹
nohup TMPDIR=/路径/tmp python main.py > ./log/running.log &
3.2.3 代码中设置
如果你在代码中想要控制临时文件的路径,可以通过 Python 的 tempfile 模块来设置。例如,使用 tempfile 时可以显式指定 dir 参数:
import tempfile
# 创建一个临时文件,临时文件存放在指定的目录中
with tempfile.TemporaryDirectory(dir="/路径/tmp") as tmpdirname:
print('Temporary directory created at', tmpdirname)
对于 PyTorch 中的 DataLoader,可以尝试设置临时路径到新目录:
import os
os.environ['TMPDIR'] = '/路径/tmp'
这样,PyTorch 生成的临时文件也会放置在你创建的新目录下,而不会出现 NFS 的问题。
4 总结
我的设置的临时文件目录是/dataNfs/tmp,这样运行的临时文件就在这里了。