当前位置: 首页 > news >正文

Linux perf probe 的使用(三)

文章目录

  • 前言
  • 一、Dynamic Tracing
  • 二、kprobes
    • 2.1 perf kprobe 的使用
    • 2.2 kprobe Arguments
    • 3.3 tcp_sendmsg()
      • 3.3.1 Kernel: tcp_sendmsg()
      • 3.3.2 Kernel: tcp_sendmsg() with size
      • 3.3.2 Kernel: tcp_sendmsg() line number and local variable
  • 三、uprobes的使用
    • 3.1 perf uprobe 的使用
    • 3.2 uprobe Arguments
  • 参考资料

前言

perf使用术语探测事件来指kprobes、uprobes和USDT探测。这些是“动态”的,必须先初始化,然后才能跟踪它们:默认情况下,它们不在perf列表的输出中(某些USDT探针可能存在,因为它们已自动初始化)。一旦初始化,它们将被列为“Tracepoint event”。

一、Dynamic Tracing

跟踪点和动态跟踪之间的区别如下图所示,该图说明了常见跟踪点库的覆盖范围:
在这里插入图片描述
图片来自于:https://www.brendangregg.com/perf.html

tracepoint和kprobe之间的比较如下表所示:
在这里插入图片描述

虽然动态跟踪可以看到所有内容,但它也是一个不稳定的接口,因为它检测原始代码。这意味着您开发的任何动态跟踪工具都可能在内核补丁或更新后崩溃。首先尝试使用静态跟踪点,因为它们的接口应该更稳定。它们也可以更容易使用和理解,因为它们的设计考虑到了跟踪最终用户。

动态跟踪的一个好处是,它可以在实时系统上启用,而无需重新启动任何东西。您可以使用已经运行的内核或应用程序,然后开始动态检测,它(安全地)修补内存中的指令以添加检测。这意味着在您开始使用该功能之前,该功能的开销为零。前一刻,您的二进制文件未经修改且全速运行,下一刻,它将运行您动态添加的一些额外的检测指令。一旦您使用完动态跟踪会话,这些指令最终应该被删除。

使用动态跟踪和执行额外指令时的开销与检测事件的频率乘以每个检测所做的工作有关。

对于内核分析,使用CONFIG_KPROBES=y和CONFIG_KPROBE_EVENTS=y来启用内核动态跟踪,而CONFIG_FRAME_POINTER=y用于基于帧指针的内核堆栈。对于用户级分析,CONFIG_UPROBES=y和CONFIG_UROBE_EVENTS=y用于用户级动态跟踪。

使用 perf-probe 命令动态跟踪函数:

NAMEperf-probe - Define new dynamic tracepointsDESCRIPTIONThis command defines dynamic tracepoint events, by symbol and registers without debuginfo, or by C expressions (C line numbers, C function names, and C local variables) with debuginfo.

常用的一些参数选项:

	   -a, --add=Define a probe event (see PROBE SYNTAX for detail).-d, --del=Delete probe events. This accepts glob wildcards(*, ?) and character classes(e.g. [a-z], [!A-Z]).-l, --list[=[GROUP:]EVENT]List up current probe events. This can also accept filtering patterns of event names. When this is used with --cache, perf shows all cached probes instead of the live probes.

二、kprobes

2.1 perf kprobe 的使用

以下是创建和使用kprobe的典型工作流,在本例中,用于检测do_nanosleep()内核函数。

动态跟踪的函数要在内核符号文件/proc/kallsyms中:

[root@localhost ~]# cat /proc/kallsyms | grep do_nanosleep
ffffffffb0f66b40 t do_nanosleep

在没有动态跟踪do_nanosleep之前:

[root@localhost ~]# perf list probe:do_nanosleepList of pre-defined events (to be used in -e):Metric Groups:

使用perf list查询不到do_nanosleep事件。

接下来动态跟踪do_nanosleep函数:

perf probe --add do_nanosleep
perf record -e probe:do_nanosleep -a sleep 5
perf script
perf probe --del do_nanosleep

kprobe是使用probe子命令和–add(–add是可选的)创建的,当不再需要它时,将使用probe和–del删除它。以下是该序列的输出,包括列出探测事件:
(1)添加动态事件:

[root@localhost ~]# perf probe --add do_nanosleep
Added new event:probe:do_nanosleep   (on do_nanosleep)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1

(2)查看动态事件(do_nanosleep初始化后,将被列为“Tracepoint event”):

[root@localhost ~]# perf list probe:do_nanosleepList of pre-defined events (to be used in -e):probe:do_nanosleep                                 [Tracepoint event]Metric Groups:

(3)record/script 动态事件

[root@localhost ~]# perf record -e probe:do_nanosleep -aR sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.618 MB perf.data (3 samples) ]
[root@localhost ~]# perf scriptsleep 30562 [001] 63910.281197: probe:do_nanosleep: (ffffffffb0f66b40)sleep 30568 [000] 63910.340391: probe:do_nanosleep: (ffffffffb0f66b40)pool  6556 [002] 63910.844546: probe:do_nanosleep: (ffffffffb0f66b40)
[root@localhost ~]# cat /proc/kallsyms | grep do_nanosleep
ffffffffb0f66b40 t do_nanosleep

(4)删除动态事件

[root@localhost ~]# perf probe --del probe:do_nanosleep
Removed event: probe:do_nanosleep

(5)kretprobe
可以通过添加%return来检测函数的返回:

[root@localhost ~]# perf probe --add do_nanosleep%return
Added new event:probe:do_nanosleep   (on do_nanosleep%return)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1

这使用kretprobe:

[root@localhost ~]# perf probe --add do_nanosleep%return
Added new event:probe:do_nanosleep   (on do_nanosleep%return)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1[root@localhost ~]#
[root@localhost ~]# perf record -e probe:do_nanosleep -aR sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.611 MB perf.data (2 samples) ]
[root@localhost ~]# perf scriptpool  6556 [000] 64259.662728: probe:do_nanosleep: (ffffffffb0f66b40 <- ffffffffb08c6a6b)sleep   518 [001] 64260.171569: probe:do_nanosleep: (ffffffffb0f66b40 <- ffffffffb08c6a6b)
[root@localhost ~]# perf probe --del probe:do_nanosleep
Removed event: probe:do_nanosleep

2.2 kprobe Arguments

至少有四种不同的方式将参数插入内核函数。

(1)
首先,如果内核debuginfo可用,那么perf可以获得函数变量(包括参数)的信息。使用–vars选项列出do_nanosleep()kprobe的变量:

-V, --vars=Show available local variables at given probe point. The argument syntax is same as PROBE SYNTAX, but NO ARGs.
[root@localhost ~]# perf probe --vars do_nanosleep
Available variables at do_nanosleep@<do_nanosleep+0>enum hrtimer_mode       modestruct hrtimer_sleeper* t

此输出显示名为mode和t的变量,它们是do_nanosleep()的入口参数。可以在创建探头时添加这些内容,以便在记录时包含这些内容。例如,添加模式:

[root@localhost ~]#  perf probe 'do_nanosleep mode'
Added new event:probe:do_nanosleep   (on do_nanosleep with mode)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1[root@localhost ~]# perf record -e probe:do_nanosleep -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.605 MB perf.data (3 samples) ][root@localhost ~]# perf scriptpool  6556 [000] 64979.664437: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1sleep  5962 [002] 64980.279301: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1pool  6556 [000] 64980.316230: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1

输出显示 mode 变量等于1。

(2)
第二,如果内核debuginfo不可用(正如我在生产中经常发现的那样),那么可以通过它们的寄存器位置读取参数。一个技巧是使用相同的系统(相同的硬件和内核)并在其上安装内核调试信息以供参考。然后,可以使用-n(dry run)和-v(verbose)选项查询此参考系统以查找寄存器位置,以执行探测:

[root@localhost ~]# perf probe -nv 'do_nanosleep mode'
......
Found 1 probe_trace_events.
Opening /sys/kernel/debug/tracing//kprobe_events write=1
Writing event: p:probe/do_nanosleep _text+7760704 mode=%si:u32
Added new event:probe:do_nanosleep   (on do_nanosleep with mode)
......

由于它是一个 dry run,因此不会创建事件。但是输出显示了模式变量的位置:它位于寄存器%si中,并打印为32位十六进制数(u32)。现在可以通过复制和粘贴模式声明字符串(mode=%si:x32)在无debuginfo系统上使用此语法:

[root@localhost ~]# perf probe 'do_nanosleep mode=%si:u32'
Added new event:probe:do_nanosleep   (on do_nanosleep with mode=%si:u32)You can now use it in all perf tools, such as:perf record -e probe:do_nanosleep -aR sleep 1[root@localhost ~]# perf record -e probe:do_nanosleep -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.606 MB perf.data (3 samples) ][root@localhost ~]# perf scriptpool  6556 [000] 65807.996795: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1sleep 11789 [002] 65808.370905: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1pool  6556 [000] 65808.648566: probe:do_nanosleep: (ffffffffb0f66b40) mode=0x1

只有当系统具有相同的处理器ABI和内核版本时,这才有效,否则可能会检测到错误的寄存器位置。

(3)
第三,如果您知道处理器ABI,可以自己确定寄存器位置。下一节中给出了一个 uprobes 的示例。

(4)
第四,有一个新的内核调试信息源:BPF类型格式(BTF)。默认情况下,这更可能是可用的,将来的perf版本应该支持它作为备用的debuginfo源。

(5)
对于使用kretprobe检测的do_nanosleep的返回,可以使用特殊的$retval变量读取返回值:

perf probe 'do_nanosleep%return $retval'

查看内核源代码以确定返回值包含的内容。

3.3 tcp_sendmsg()

3.3.1 Kernel: tcp_sendmsg()

此示例显示在Linux 3.10.0内核上检测内核tcp_sendmsg()函数:

[root@localhost perf]# cat /proc/kallsyms | grep tcp_sendmsg
ffffffffb0e93fc0 T tcp_sendmsg
[root@localhost perf]# perf probe --add tcp_sendmsg
Added new event:probe:tcp_sendmsg    (on tcp_sendmsg)You can now use it in all perf tools, such as:perf record -e probe:tcp_sendmsg -aR sleep 1[root@localhost perf]# perf record -e probe:tcp_sendmsg -a -g -- sleep 5
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.632 MB perf.data (42 samples) ]
[root@localhost perf]# perf report --stdio
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 42  of event 'probe:tcp_sendmsg'
# Event count (approx.): 42
#
# Children      Self  Trace output
# ........  ........  ..................
#100.00%   100.00%  (ffffffffb0e93fc0)|---__GI___libc_writesystem_callsys_writevfs_writedo_sync_writesock_aio_writetcp_sendmsg#
# (Tip: For memory address profiling, try: perf mem record / perf mem report)

这显示了write()系统调用到tcp_sendmsg()的路径。

[root@localhost perf]# perf probe --del tcp_sendmsg
Removed event: probe:tcp_sendmsg

3.3.2 Kernel: tcp_sendmsg() with size

如果内核具有debuginfo(CONFIG_DEBUG_INFO=y),则可以从函数中找出内核变量。这是检查size_ t(整数)的简单示例:
列出tcp_sendmsg()可用的变量:

-V, --vars=Show available local variables at given probe point. The argument syntax is same as PROBE SYNTAX, but NO ARGs.
[root@localhost perf]# perf probe -V tcp_sendmsg
Available variables at tcp_sendmsg@<tcp_sendmsg+0>int     size_goallong int        timeosize_t  sizestruct kiocb*   iocbstruct msghdr*  msgstruct sock*    sk

使用“size”变量为tcp_sendmsg()创建探测:

[root@localhost perf]# perf probe --add 'tcp_sendmsg size'
Added new event:probe:tcp_sendmsg    (on tcp_sendmsg with size)You can now use it in all perf tools, such as:perf record -e probe:tcp_sendmsg -aR sleep 1

Tracing this probe:

[root@localhost perf]# perf record -e probe:tcp_sendmsg -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.628 MB perf.data (49 samples) ][root@localhost perf]# perf scriptsshd 29204 [001] 82790.664230: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82790.664939: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x60sshd 29204 [001] 82790.665627: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82790.665712: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82790.667466: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82790.667566: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82790.668484: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82790.668582: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.672211: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82791.674832: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x60sshd 29204 [001] 82791.677249: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82791.677519: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.681480: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82791.681772: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.684988: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82791.685259: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30sshd 29204 [001] 82792.689914: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x40sshd 29204 [001] 82792.692504: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x60sshd 29204 [001] 82792.694701: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x50sshd 29204 [001] 82792.694949: probe:tcp_sendmsg: (ffffffffb0e93fc0) size=0x30......

3.3.2 Kernel: tcp_sendmsg() line number and local variable

使用debuginfo,perf_events可以为内核函数内的行创建跟踪点。列出tcp_sendmsg()的可用行探测:

-L, --line=Show source code lines which can be probed. This needs an argument which specifies a range of the source code. (see LINE SYNTAX for detail)
[root@localhost perf]# perf probe -L tcp_sendmsg
<tcp_sendmsg@/usr/src/debug/kernel-3.10.0-957.el7/linux-3.10.0-957.el7.x86_64/net/ipv4/tcp.c:0>0  int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,size_t size)2  {struct iovec *iov;struct tcp_sock *tp = tcp_sk(sk);struct sk_buff *skb;6         int iovlen, flags, err, copied = 0;7         int mss_now = 0, size_goal, copied_syn = 0, offset = 0;bool sg;long timeo;11         lock_sock(sk);13         flags = msg->msg_flags;14         if (flags & MSG_FASTOPEN) {15                 err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);16                 if (err == -EINPROGRESS && copied_syn > 0)goto out;18                 else if (err)goto out_err;offset = copied_syn;}......}
[root@localhost perf]# perf probe -V tcp_sendmsg:81
Available variables at tcp_sendmsg:81@<tcp_sendmsg+826>bool    sgint     copiedint     flagsint     iovlenint     mss_nowint     offsetint     size_goallong int        timeosize_t  seglenstruct iovec*   iovstruct sock*    skunsigned char*  from

现在让我们跟踪第81行,并在循环中检查seglen变量:

[root@localhost perf]# perf probe --del tcp_sendmsg
Removed event: probe:tcp_sendmsg
[root@localhost perf]# perf probe --add 'tcp_sendmsg:81 seglen'
Added new event:probe:tcp_sendmsg    (on tcp_sendmsg:81 with seglen)You can now use it in all perf tools, such as:perf record -e probe:tcp_sendmsg -aR sleep 1[root@localhost perf]# perf record -e probe:tcp_sendmsg -a
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.619 MB perf.data (33 samples) ][root@localhost perf]# perf scriptsshd 29204 [001] 83979.203223: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [001] 83979.205938: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x60sshd 29204 [001] 83979.208299: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [001] 83979.208539: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83979.214403: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [001] 83979.214656: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83979.218265: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83979.218564: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83980.223443: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [001] 83980.226039: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [001] 83980.226248: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x70sshd 29204 [002] 83980.229020: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83980.229094: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83980.232982: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83980.233220: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83980.236385: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83980.236677: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.241734: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83981.244477: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x60sshd 29204 [002] 83981.246985: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83981.247241: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.251093: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83981.251360: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.254500: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83981.254828: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.259723: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83982.262445: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x60sshd 29204 [002] 83982.264933: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x50sshd 29204 [002] 83982.265127: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.268984: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x40sshd 29204 [002] 83982.269206: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.272402: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30sshd 29204 [002] 83982.272704: probe:tcp_sendmsg: (ffffffffb0e942fa) seglen=0x30

还可以在内核过滤中使用–filter,以仅匹配所需的数据。

三、uprobes的使用

uprobes(用户空间探测器)与kprobes类似,但适用于用户空间。它们可以动态地插入应用程序和库中的函数,并提供一个不稳定的API,用于深入其他工具范围之外的软件内部。uprobes在2012年发布的Linux3.5中提供。

3.1 perf uprobe 的使用

在使用 perf 时,uprobes的创建与kprobes类似。例如,要为libc文件打开函数创建uprobe,fopen:

# perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add fopen
Added new event:probe_libc:fopen (on fopen in /lib/x86_64-linux-gnu/libc-2.27.so)

二进制路径使用-x指定。uprobe名为probe_libc:fopen,现在可以与perf record一起使用来记录事件。

完成uprobe后,可以使用–del:

# perf probe --del probe_libc:fopen
Removed event: probe_libc:fopen

可以通过添加%return来检测函数的返回:

# perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add fopen%return

使用uretpobe。

3.2 uprobe Arguments

如果您的系统具有目标二进制文件的debuginfo,则变量信息(包括参数)可能可用。这可以使用–vars列出:

# perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --vars fopen
Available variables at fopen@<_IO_vfscanf+15344>char* filenamechar* mode

输出显示fopen具有 filename 和 mode 变量。创建探针时可以添加以下内容:

perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add 'fopen filename mode'

Debuginfo可以通过-dbg或-dbgsym包提供。如果这在目标系统上不可用,但在另一个系统上,则其他系统可以用作参考系统,如前一节kprobes中所示。

参考资料

https://www.brendangregg.com/perf.html

相关文章:

Linux perf probe 的使用(三)

文章目录前言一、Dynamic Tracing二、kprobes2.1 perf kprobe 的使用2.2 kprobe Arguments3.3 tcp_sendmsg()3.3.1 Kernel: tcp_sendmsg()3.3.2 Kernel: tcp_sendmsg() with size3.3.2 Kernel: tcp_sendmsg() line number and local variable三、uprobes的使用3.1 perf uprobe …...

python GUI编程 多窗口跳转

# 多窗口跳转例子from tkinter import *def main(): # 主窗体def goto(num):root.destroy() # 关闭主窗体if num 1:one() # 进入第1个窗体elif num 2:two() # 进入第2个窗体root Tk()root.geometry(300x150600200)root.title(登录窗口)but1 Button(root, text"进入…...

nuxt 学习笔记

这里写目录标题路由跳转NuxtLinkquery参数params参数嵌套路由tab切换效果layouts 文件夹强制约定放置所有布局文件&#xff0c;并以插槽的形式作用在页面中1.在app.vue里面2.component 组件使用Vue < component :is"">Vuex生命周期数据请求useFetchuseAsyncDat…...

Python编程自动化办公案例(1)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.使用库讲解 1.xlrd 2.xlwt 二.主要案例 1.批量合并 模板如下&#xf…...

一站式 Elasticsearch 集群指标监控与运维管控平台

上篇文章写了一下消息运维管理平台&#xff0c;今天带来的是ES的监控和运维平台。目前初创企业&#xff0c;不像大型互联网公司&#xff0c;可以重复的造轮子。前期还是快速迭代试错阶段&#xff0c;方便拿到市场反馈&#xff0c;及时调整自己的战略和产品方向。让自己活下去&a…...

C# 调用Python

一、简介 IronPython 是一种在 NET 和 Mono 上实现的 Python 语言&#xff0c;由 Jim Hugunin&#xff08;同时也是 Jython 创造者&#xff09;所创造。 Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python是…...

51单片机最强模块化封装(3)

文章目录 前言一、创建smg文件,添加smg文件路径二、smg文件编写三、模块化测试总结前言 本篇文章将带大家继续封装我们的代码。 这里我们会封装数码管的操作函数。 一、创建smg文件,添加smg文件路径 这里的操作就不过多解释了,大家自行看前面的文章即可。 51单片机模块化…...

【CSS 布局】水平垂直居中

CSS 布局-水平垂直居中 一、水平居中 创建一个父盒子&#xff0c;和子盒子 <div class"parent"><div class"child"></div> </div>基本样式如下 .parent {background-color: #fff; }.child {background-color: #999;width: 100p…...

【C++】类和对象--类的6个默认成员函数

目录1.类的6个默认成员函数2.构造函数2.1概念2.2特性3.析构函数3.1概念3.2特性4.拷贝构造函数4.1概念4.2特征5.赋值运算符重载5.1运算符重载5.2赋值运算符重载5.3前置和后置重载5.4流插入和流提取运算符重载6.const成员7.取地址重载和const取地址操作符重载1.类的6个默认成员函…...

常见面试题---------如何处理MQ消息丢失的问题?

如何处理MQ消息丢失的问题? RabbitMQ丢失消息分为如下几种情况&#xff1a; 生产者丢消息&#xff1a; 生产者将数据发送到RabbitMQ的时候&#xff0c;可能在传输过程中因为网络等问题而将数据弄丢了。 RabbitMQ自己丢消息&#xff1a; 如果没有开启RabbitMQ的持久化&#x…...

十四、Linux网络:高级IO

目录 五种IO模型 同步IO 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO...

带你走进API安全的知识海洋

Part1什么是API API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c;或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访…...

【Java】TCP的三次握手和四次挥手

三次握手 TCP三次握手是一个经典的面试题&#xff0c;它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接&#xff0c;并进行数据传递。&#xff08;客户端主动发起的&#xff09;TCP之所以需要三次握手是因为TCP双方都是全双工的。 什么是全双工&#xff1f; TCP任何…...

JUC并发编程

1.什么是JUC java.util工具包、包、分类 业务&#xff1a;普通业务线程代码 Thread Runable: 没有返回值、效率相比Callable相对较低。 2.线程和进程 进程&#xff1a;一个程序&#xff0c;QQ.exe Music.exe 程序的集合 一个进程往往可以包含多个线程&#xff0c;至少包含一个…...

概率统计·假设检验【正态总体均值的假设检验、正态总体方差的假设检验】

均值假设检验定义 2类错误 第1类错误&#xff08;弃真&#xff09;&#xff1a;当原假设H0为真&#xff0c;观察值却落入拒绝域&#xff0c;因而拒 绝H0这类错误是“以真为假” 犯第一类错误的概率显著性水平α第2类错误&#xff08;取伪&#xff09;&#xff1a;当原假设H0不…...

如何预测机组设备健康状态?你可能需要这套解决方案

1. 应用场景随机振动[注1]会发生在工业物联网的各个场景中&#xff0c;包括产线机组设备的运行、运输设备的移动、试验仪器的运行等等。通过分析采集到的振动信号可以预估设备的疲劳年限、及时知晓设备已发生的异常以及预测未来仪器可能发生的异常等等。本篇教程会提供给有该方…...

C++类和对象:面向对象编程的核心。| 面向对象还编什么程啊,活该你是单身狗。

&#x1f451;专栏内容&#xff1a;C学习笔记⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、面向对象编程三、类和对象1、类的引入2、类的定义Ⅰ、声明和定义在一起Ⅱ、声明和定义分开Ⅲ、成员变量命…...

CUDA虚拟内存管理

CUDA中的虚拟内存管理 文章目录CUDA中的虚拟内存管理1. Introduction2. Query for support3. Allocating Physical Memory3.1. Shareable Memory Allocations3.2. Memory Type3.2.1. Compressible Memory4. Reserving a Virtual Address Range5. Virtual Aliasing Support6. Ma…...

线程池小结

什么是线程池 线程池其实就是一种多线程处理形式&#xff0c;处理过程中可以将任务添加到队列中&#xff0c;然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象; 为什么使用线程池 …...

vue3状态管理模式 Pinia

状态管理库 Pinia是Vue的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态 1&#xff1a;安装与使用pinia 1.1 安装语法&#xff1a;npm install pinia1.2 创建一个pinia&#xff08;根存储&#xff09;并将其传递给应用程序 import { createApp } from vue import…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...

路由基础-路由表

本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中&#xff0c;往往存在多个不同的IP网段&#xff0c;数据在不同的IP网段之间交互是需要借助三层设备的&#xff0c;这些设备具备路由能力&#xff0c;能够实现数据的跨网段转发。 路由是数据通信网络中最基…...