在没有 USR1 的情况下检查 dd 的进度吗?

在没有 USR1 的情况下检查 dd 的进度吗?

我使用的是busybox 1.27纯 Linux 系统,因此没有output=progress可用的,没有 busybox 自己的实现,也没有pv它本身。pipe_progresspv

我有两个问题。第一个是基于https://www.linux.com/training-tutorials/show-progress-when-using-dd/。它表示,通过USR1向其发送信号会dd“暂停”该过程,并且dd在打印后其当前状态将继续其正在执行的工作。我正在尝试进行一些基准测试,dd因此我希望对dd操作的影响最小。我希望每秒获得当前操作的输出,因为传递的数据dd是波动的,识别传输速率何时下降对我来说很重要。

第一个问题: 每次收到信号时“dd”都会“暂停”,这是真的吗USR1

如果dd每秒暂停一次,那么当传输数十千兆字节时,我将增加操作时间。

第二个问题: 假设是的作为第一个问题的答案,我想知道是否可以在dd不向进程发送任何信号的情况下打印其当前状态,也许是某种重定向STDOUT(如 2>&1)?

我指的是:

# bs with 1Mib so I can have more control on the test.
dd if=/dev/zero of=/dev/null bs=1048576 count=1024

# Printing current operation status.
sudo kill -USR1 $dd_pid 

答案1

dd if=/dev/zero of=/dev/null bs=1048576 count=1024

注意dd可以破坏数据, 至少使用bs参数时。和其性能优势如果您为特定的系统配置手动选择最佳块大小,那么充其量是很小的:cat或者cp可以做得更好,最多只是稍微慢一点。所以dd如果没有必要就不要使用。

请注意,从 1.23 版本开始,BusyBox 使用sendfile系统调用来复制数据,而不是使用readand write。然而,只有诸如cat和 之类的普通副本才cp使用sendfiledd被迫使用read/write因为它需要精确控制大小。因此,BusyBox ≥1.23,cat并且cp很可能比dd.

'dd' 每次收到 USR1 信号时都会“暂停”,这是真的吗?

从技术上讲,是的,它必须“暂停”来处理信号。然而,暂停只是几个 CPU 指令(迄今为止成本最高的部分是打印进度输出)。所以这不会以任何方式使你的基准失效。

如果 dd 每秒暂停一次,那么当传输数十 GB 数据时,我将增加操作时间。

不,你的数量级错了。您可能会在单 CPU 线程上增加 0.1% 的时间。主要成本是基准测试程序的内核时间,而不是dd,因此它是您想要执行的操作所固有的,而不是您实现它的方式。

是否可以让 dd 打印其当前状态而不向进程发送任何信号

嗯,不。已经有一种简单的、历史上确立的、标准的、容易的方法来做到这一点。为什么会有另一种更难实施的方式呢?


在 Linux 上,有一种通用方法可以知道副本已到达的点。它并不取决于哪个程序正在执行复制,尽管它并不总是适用于特殊文件。找出$pid正在执行复制的进程 ID,以及它用于输入和输出的文件描述符。dd从 fd 0 读取并写入 fd 1。BusyBoxcp通常从 fd 3 读取并写入 fd 4。您可以通过 中的符号链接检查哪个文件在哪个文件描述符上打开/proc/$pid/fd

$ cp /dev/zero /dev/null & pid=$!
$ readlink /proc/$pid/fd/3
/dev/zero
$ readlink /proc/$pid/fd/4
/dev/null

您可以检查文件描述符$n$中的位置/proc/$pid/fd/$n

$ cat /proc/$pid/fdinfo/4
pos:    74252288
flags:  0100001
mnt_id: 27

但是,请注意,文件描述符位置可能不会使用特殊文件(例如/dev/zero/dev/null、管道或套接字)进行更新。它始终使用常规文件进行更新。我不知道它是否针对块设备进行了更新。因此,它可能不会为您提供任何在/dev/zero和之间复制的信息/dev/null,但它可能适用于您的实际用例。

答案2

您还可以通过界面查询进度/proc

# dd bs=1M if=/dev/mmcblk0 of=/dev/null &
# pidof dd
1358

因此,有关此过程的信息可以在以下位置找到/proc/1358

# ls -l /proc/1358/fd
total 0
lr-x------    1 root     root            64 Nov  2 09:16 0 -> /dev/mmcblk0
l-wx------    1 root     root            64 Nov  2 09:16 1 -> /dev/null
lrwx------    1 root     root            64 Nov  2 09:16 2 -> /dev/pts/0

文件句柄 0 是if=/dev/mmcblk0,现在进度在哪里?

# cat /proc/1358/fdinfo/0
pos:    2132803584
flags:  0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos:    2366636032
flags:  0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos:    2587885568
flags:  0400000
mnt_id: 17

通过这种方式,对于 busybox dd,您还可以从其 fdinfo pos 值获取进度。

也就是说,适度发送 USR1 信号对性能的影响应该很小。在资源很少的嵌入式系统上,轮询 fdinfo 也可能会产生类似的影响。

相关内容