文章851
标签121
分类10

Linux性能分析工具 : Perf

当使用perf工具进行性能分析时,可以通过以下步骤来获取系统和应用程序的性能数据,并通过分析结果来优化性能。本篇博客将介绍perf工具的基本使用方法和示例。

Perf工具简介

perf是一个功能强大的Linux性能分析工具,它可以帮助开发者定位和解决性能问题。它提供了多种功能,包括采样分析、事件计数、跟踪和调试等。下面将介绍几个常用的perf命令。

安装perf工具

perf工具通常随Linux内核一起发布,可以通过以下命令安装:

sudo apt-get install linux-tools-common linux-tools-$(uname -r)

基本命令

  1. 采样分析

采样分析是perf工具的一项重要功能,它通过在一段时间内对CPU进行采样,收集程序运行时的函数调用栈。可以使用以下命令进行采样分析:

perf record -g <command>
perf report
  1. 事件计数

perf工具可以对指定的硬件事件进行计数,以便了解系统和应用程序的性能指标。可以使用以下命令进行事件计数:

perf stat <command>
  1. 跟踪

perf工具可以对系统和应用程序进行跟踪,以查看其在执行过程中的行为和性能。可以使用以下命令进行跟踪:

perf trace <command>

示例

接下来,我们将通过一个示例来演示perf工具的使用。假设我们有一个C程序,文件名为example.c,代码如下:

#include <stdio.h>

void expensive_function() {
    // 模拟一个耗时较长的函数
    for (int i = 0; i < 100000000; i++) {
        // 空循环
    }
}

int main() {
    printf("Start\n");
    expensive_function();
    printf("End\n");
    return 0;
}

我们的目标是使用perf工具来分析expensive_function()函数的性能。

采样分析

首先,使用以下命令编译并运行程序:

gcc -o example example.c
./example

然后,使用perf工具进行采样分析:

perf record -g ./example
perf report

执行perf record -g ./example命令后,perf将在程序运行时进行采样,并将采样数据保存到文件中。然后,执行perf report命令来查看采样结果。在报告中,可以看到函数调用栈和各个函数的耗时信息,从而确定性能瓶颈所在。

事件计数

除了采样分析,我们还可以使用perf工具进行事件计数。在这个示例中,我们将计算程序的指令数和CPU周期数:

perf stat -e instructions,cycles ./example

执行以上命令后,perf将运行程序,并显示指令数和CPU周期数的统计结果。

跟踪

最后,我们可以使用perf工具对程序进行跟踪,以查看其在执行过程中的行为:

perf trace ./example

执行以上命令后,perf将跟踪程序的系统调用、函数调用等事件,并输出相应的跟踪结果。

总结

本篇博客介绍了perf工具的基本使用方法和示例。通过采样分析、事件计数和跟踪,我们可以获取系统和应用程序的性能数据,并通过分析结果来优化性能。perf工具提供了丰富的功能和选项,可以根据具体需求进行更详细的性能分析和调优。

以上是perf工具的简单介绍和示例。以下是使用Markdown格式编写的perf工具使用的博客:

# Perf工具的使用

当涉及到性能分析时,perf工具是一个强大且广泛使用的工具。它可以帮助我们收集系统和应用程序的性能数据,并通过分析结果来优化性能。在本篇博客中,我们将介绍perf工具的基本使用方法和示例。

## Perf工具简介

perf是一个功能强大的Linux性能分析工具,它提供了多种功能,包括采样分析、事件计数、跟踪和调试等。以下是几个常用的perf命令:

### 安装perf工具

可以使用以下命令安装perf工具:

sudo apt-get install linux-tools-common linux-tools-$(uname -r)


### 基本命令

1. 采样分析

采样分析是perf工具的重要功能之一。它通过在一段时间内对CPU进行采样,收集程序运行时的函数调用栈。以下是采样分析的基本步骤:

perf record -g
perf report


2. 事件计数

perf工具可以对指定的硬件事件进行计数,以了解系统和应用程序的性能指标。以下是事件计数的基本步骤:

perf stat


3. 跟踪

perf工具可以对系统和应用程序进行跟踪,以查看其在执行过程中的行为和性能。以下是跟踪的基本步骤:

perf trace


## 示例

接下来,我们将通过一个示例来演示perf工具的使用。假设我们有一个C程序,文件名为`example.c`,代码如下:

include <stdio.h>

void expensive_function() {

// 模拟一个耗时较长的函数
for (int i = 0; i < 100000000; i++) {
    // 空循环
}

}

int main() {

printf("Start\n");
expensive_function();
printf("End\n");
return 0;

}


我们的目标是使用perf工具来分析`expensive_function()`函数的性能。

### 采样分析

首先,使用以下命令编译并运行程序:

gcc -o example example.c
./example


然后,使用perf工具进行采样分析:

perf record -g ./example
perf report


执行`perf record -g ./example`命令后,perf将在程序运行时进行采样,并将采样数据保存到文件中。然后,执行`perf report`命令来查看采样结果。在报告中,可以看到函数调用栈和各个函数的耗时信息,从而确定性能瓶颈所在。

### 事件计数

除了采样分析,我们还可以使用perf工具进行事件计数。在这个示例中,我们将计算程序的指令数和CPU周期数:

perf stat -e instructions,cycles ./example


执行以上命令后,perf将运行程序,并显示指令数和CPU周期数的统计结果。

### 跟踪

最后,我们可以使用perf工具对程序进行跟踪,以查看其在执行过程中的行为:

perf trace ./example


执行以上命令后,perf将跟踪程序的系统调用、函数调用等事件,并输出相应的跟踪结果。

## 总结

如何查看 进程已经创建了多少子进程

要查看一个进程已经创建了多少子进程,可以通过使用系统工具和命令来获取相关信息。下面是几种常用的方法:

  1. 使用ps命令:

    ps -eLf | grep <进程ID>
    ```
    用上述命令替换`<进程ID>`为你要查看的进程的ID。这会列出指定进程及其子进程的详细信息,包括进程ID(PID)和父进程ID(PPID)。
  2. 使用pstree命令:

    pstree -p <进程ID>
    ```
    同样,将`<进程ID>`替换为你要查看的进程的ID。`pstree`命令会以树状结构显示进程及其子进程的关系,包括对应的进程ID。
  3. 使用pgrep命令:

    pgrep -P <进程ID> | wc -l
    ```
    这个命令会统计指定进程的子进程数量。将`<进程ID>`替换为你要查看的进程的ID。`pgrep -P <进程ID>`会列出指定进程的所有子进程的ID,通过`wc -l`命令可以计算出子进程的数量。

请注意,以上命令在不同的操作系统和版本中可能会有所差异。你可以根据自己的操作系统选择适用的命令,并根据需要进行进一步的处理和筛选。

Swoole 抛错 : WARNING ProcessPool::spawn(): fork() failed, Error: Resource temporarily unavailable[11]

这个错误表示在Swoole中使用ProcessPool::spawn()方法创建子进程时,fork()系统调用失败了。错误消息中的"Resource temporarily unavailable"表示资源暂时不可用,错误码为11。

这种错误通常是由于操作系统限制导致的。在Linux系统中,每个进程都有一个"最大进程数"限制,即每个用户(或进程)可以创建的最大子进程数量。当达到该限制时,fork()系统调用将无法创建新的进程,从而引发这个错误。

解决这个问题的方法包括:

  1. 增加系统的"最大进程数"限制:可以通过修改Linux系统的ulimit设置来增加每个用户(或进程)可创建的最大进程数。可以使用ulimit -u命令查看当前的限制,并使用ulimit -u <new_limit>命令来修改限制值。
  2. 优化进程使用:检查代码中是否存在创建大量子进程的情况,是否可以通过调整逻辑或使用进程池等方式减少子进程的数量,从而避免达到系统限制。
  3. 检查系统资源:确保系统资源(如内存、文件描述符等)没有达到极限,导致无法创建新的进程。可以通过ulimit命令或其他系统监控工具来查看系统资源的使用情况。

需要注意的是,修改系统的限制可能需要root权限。在实际操作中,请确保了解系统的限制和可能的影响,并谨慎进行修改。

PHP IP 处理 ip2long() 和 inet_pton()

这两个方法 ip2long()inet_pton() 都是用于处理 IP 地址的函数,但是它们在处理的方式和支持的 IP 地址类型上有所不同。

  1. ip2long($ip)

    • ip2long() 是一个 PHP 内置函数,用于将 IPv4 地址(点分十进制表示)转换为对应的无符号长整型数值。
    • 它接受一个 IPv4 地址作为参数,并返回对应的无符号长整型数值。如果输入的 IP 地址格式不正确,则返回 false
    • 示例:

      $ip = '192.168.0.1';
      $ipNum = ip2long($ip);
      echo $ipNum;  // 输出:3232235521
  2. inet_pton($ip)

    • inet_pton() 是一个 PHP 内置函数,用于将 IPv4 或 IPv6 地址转换为对应的二进制表示。
    • 它接受一个 IP 地址作为参数,并返回一个包含二进制表示的字符串。如果输入的 IP 地址格式不正确,则返回 false
    • inet_pton() 可以处理 IPv4 和 IPv6 地址。
    • 示例:

      $ipv4 = '192.168.0.1';
      $ipv6 = '2001:0db8:85a3:0000:0000:8a2e:0370:7334';
      
      $ipv4Binary = inet_pton($ipv4);
      echo bin2hex($ipv4Binary);  // 输出:c0a80001
      
      $ipv6Binary = inet_pton($ipv6);
      echo bin2hex($ipv6Binary);  // 输出:20010db885a3000000008a2e03707334

需要注意的是,ip2long() 只能处理 IPv4 地址,而 inet_pton() 可以处理 IPv4 和 IPv6 地址。在使用这两个函数时,应根据需要选择适当的函数来处理对应的 IP 地址类型。

MySQL中Decimal类型和Float/Double等区别

MySQL中Decimal类型和Float/Double等区别

在MySQL中,存在floatdouble等非标准数据类型,以及decimal这种标准数据类型。它们之间的区别如下:

  • floatdouble等非标准类型在数据库中保存的是近似值,而decimal则以字符串的形式保存数值。
  • floatdouble类型可以存储浮点数(即小数类型),但是float有一个问题,当给定的数据是整数时,它会以整数形式存储。这在处理货币值时会遇到问题,例如,如果默认值为0.00,实际存储的却是0;同样,如果存储货币值为12.00,实际存储的是12。
  • 幸好MySQL提供了decimal这个数据类型,它可以轻松解决上述问题。decimal类型在MySQL中以相同的类型实现,这符合SQL92标准。它们用于保存对准确精度有重要要求的值,例如与金钱有关的数据。

数据定义

  • float(M,S):其中M表示全长,S表示小数点后的长度。以下是一个示例:
CREATE TABLE t1 (c1 float(10,2), c3 decimal(10,2));
INSERT INTO t1 VALUES (9876543.21, 9876543.12);
SELECT * FROM t1;

输出结果如下:

+------------+------------+
|     c1     |     c3     |
+------------+------------+
| 9876543.00 | 9876543.12 |
+------------+------------+
  • 再举一个例子:DECIMAL(5,2)
CREATE TABLE t1 (id1 float(5,2) DEFAULT NULL, id2 double(5,2) DEFAULT NULL, id3 decimal(5,2) DEFAULT NULL);
INSERT INTO t1 VALUES (1.2345, 1.2345, 1.2345);
SHOW WARNINGS;

输出结果如下:

+-------+------+------------------------------------------+
| Level | Code |                  Message                 |
+-------+------+------------------------------------------+
| Note  | 1265 | Data truncated for column 'id3' at row 1 |
+-------+------+------------------------------------------+

解释:

  • 1.2345:小数点后最多2位,可以保存,但会有一个警告。
  • 12.34:符合限制,可以保存。
  • 1234.5:小数部分未满2位,需要补0,应该保存为1234.50。但整个位数超过了5,保存时报错。
  • 1.2:小数部分未满2位,需要补0,按照1.20保存。

默认状态比较

  • 浮点数如果不指定精度和标度,会按照实当然可以!下面是您可以直接复制到博客中的Markdown格式的文本:

在MySQL中,存在floatdouble等非标准数据类型,以及decimal这种标准数据类型。它们之间的区别如下:

  • 存储方式:floatdouble类型以二进制形式存储近似值,而decimal类型以字符串形式存储数值。
  • 精度:floatdouble类型是近似值,其精度取决于所分配的存储空间。而decimal类型是精确值,它以指定的精度和标度来存储数据。
  • 存储空间:floatdouble类型的存储空间是固定的,它们分别占用4字节和8字节。而decimal类型的存储空间是可变的,它的长度取决于指定的精度和标度。

在使用这些数据类型时,需要根据具体的需求来选择合适的类型。如果需要存储对精度要求较高的数据,特别是涉及货币等需要精确计算的场景,建议使用decimal类型。而对于一般的科学计算等情况,floatdouble类型可能更为适用。


请注意,以上文本已经使用Markdown格式编写,您可以直接将其复制到您的博客编辑器中,并进行格式化和发布。

">