Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Yveltals Blog

Cgroup

进程绑核

1
2
3
4
5
6
7
8
9
10
cd /sys/fs/cgroup/cpuset
mkdir mygroup && cd mygroup
## 避免报错 write error: No space left on device
echo 0 > cpuset.mems
## 限制进程运行在对应的 processor
echo "0-19,40-59" > cpuset.cpus
## 进程加入 cgroup
echo 4462 > cgroup.proc
## 加入上级解除限制(或等进程结束)
echo 4462 > ../cgroup.procs

Linux Cgroup系列(04):限制cgroup的内存使用

火焰图生成与解析

  1. 环境准备
1
2
3
4
# 安装 Linux 系统的 perf 工具
yum -y install perf
# 下载生成火焰图的工具
git clone https://github.com/brendangregg/FlameGraph.git
  1. 数据采样,解析生成火焰图
1
2
perf record -a -g -F99 --call-graph dwarf -p <pid> sleep 30
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > process.svg
  1. 常用命令
1
2
3
4
5
6
7
-p <pid>:指定待分析进程的 pid(多个用,分隔列表)
-t <tid>:指定待分析线程的 tid(多个用,分隔列表)
-a:从所有 CPU 收集系统数据
-g:开启 call-graph (stack chain/backtrace) 记录
-C <cpu-list>:只统计指定 CPU 列表的数据,如:0,1,3或1-2
-F <n>:每秒采样 n 次
-o <output.data>:指定输出文件output.data,默认输出到perf.data
  1. perf 火焰图大量 unknown 的问题

在实际使用过程中发现,简单的使用 perf record -g 获取到的调用栈是有问题的,存在大量 Unknown 函数,从 perf report 的结果来看这些部分对应地址大部分都是非法地址,且生成的火焰图中存在很多明显与代码矛盾的调用关系。

perf 同时支持 3 种栈回溯方式:fp, dwarf, lbr,可以通过 --call-graph 参数指定,而 -g 就相当于 --call-graph fp

优点 缺点
fp None 默认 fp 被优化掉了根本不可用
lbr 高效准确 较新的 Intel CPU 才有此功能,能记录的调用栈深度有限
dwarf 准确 开销相对较大,需要编译时加 -g

Linux命令

网络与进程

  • netstat -anp | grep 20501 查看端口占用,netstat -i 网卡信息
  • ipcs 显示共享内存段、消息队列和信号量的信息
  • ifconfig 显示或设置网络设备,配置IP、MAC地址、启动网卡
  • lsof 查看文件被哪个进程修改lsof tmp.txt,查看端口占用 lsof -i :8080
  • fdisk 创建和维护分区表
  • tcpdump 抓包
  • route 查看路由
  • pgrep dummy 查看进程号,-l显示进程名
  • pkill dummy Kill进程名,-f全匹配command line
  • ps aux | grep -w 'hello' | grep -v grep | awk '{print $2}' | xargs kill -9
  • cmd1 | xargs -I {} cmd2 {} 将 cmd1 的每行输出作为 cmd2 的输入,{}仅作为占位符,换成如 $ 均可

文件操作

  • sed -i "s/查找字段/替换字段/g" a.txt
  • awk -i '{print $1}' 空格分割,打印第一个。或 awk -F ',' '{print $1}' 指定 , 分割
  • diff <(sort a.txt) <(sort b.txt)
  • comm <(sort a.txt) <(sort b.txt) 比较排序文件,展示三列分别为:只在第一个文件、只在第二个文件、两文件都出现的行
  • headlink -f . 查看当前路径
  • zxvf xxx.tar.gz -C dst_dir/ > /dev/null 2>&1 解压缩
  • mount挂载
    • 硬盘:mount 设备 挂载点
    • 镜像:mount -o rw -t iso9660 设备 挂载点,rw读写,ro只读

Shell编程

中控机命令

1
2
scp /home/web_server/mazhuang/load.sh web_server@${host}:/home/web_server/mazhuang/
ssh -n ${host} "sh /home/web_server/mazhuang/load.sh"

Kill进程

1
2
3
4
5
6
7
pkill -f $directory/dummy
until [[ -z `ps aux | awk '{print $11}' | grep -v grep | grep "$directory/dummy"` ]]; do
sleep 1s
done
if [[ -z `ps aux | awk '{print $11}' | grep -v grep | grep "dummy"` ]]; then
echo -e "\e[31mWARNING: Failed to kill a process. \e[0m"
fi

Vim

命令模式

级别 操作符 说明
行级 0 光标移动到当前行首字符
段落级 { 光标移动到段落首字符
段落级 } 光标移动到段落尾字符
屏幕级 H 光标移动到屏幕首行首字符
屏幕级 L 光标移动到屏幕尾行首字符
文档级 G 光标移动到文档尾行首字符
段落级 y{ 从段落首字符开始复制直到当前字符(不包括)
段落级 y} 从当前字符开始复制直到段落尾字符(包括)
文档级 yG 从当前行开始复制直到文档尾行(包括)

底行模式

操作符 说明
:s/被替换/替换/ 替换当前行的第一目标
:s/被替换/替换/g 替换当前行的全部目标
:%s/被替换/替换/g 替换整个文档的全部目标
:%s/被替换/替换/gc 替换文档全部目标并询问
设置 说明
set number 设置行号
set smartindent 智能对⻬
set cindent C语言格式对⻬
set showmatch 括号匹配
set tabstop=2 Tab为2个空格
set mouse=a 鼠标支持

调试

GDB断点的原理:

  1. 断点替换:在指定的地址处,GDB 会替换原有的指令为 int 3 中断指令。当程序执行到该位置时,会产生一个中断信号。GDB 捕获信号后,会停止程序进入调试模式。
  2. 保存原指令:GDB 会保存被替换的原始指令,以便在断点被移除时能够恢复。
命令 含义
gdb attach 调试附加到进程
gcore 生成core
pstack 查看栈帧信息
info registers / print $eax 查看寄存器值

C/C++编译

g++编译参数

  • -g 编译带调试信息的可执行文件

  • -o 指定输出文件名

  • -O2 优化源代码

  • -Wall 打印警告信息,-w 关闭警告信息

  • -std=c++11 设置编译标准

  • -D 定义宏

    1
    g++ -D USERM test.cpp
  • -l 指定库文件 -L指定库文件路径

    1
    2
    3
    4
    # 库文件在/lib和/usr/lib和/usr/local/lib里直接用-l链接
    g++ -lpthread test.cpp
    # 库文件不在上面三个目录里用-L指定库文件目录
    g++ -L/home/yveltal/mylibfolder -lmytest test.cpp
  • -I 指定头文件搜索目录

    1
    2
    # 头文件不在/usr/include里用I参数指定,相对路径可以用-I.来指定
    g++ -I/myinclude test.cpp

Cmake

指定特定版本gcc

服务器上有多个版本gcc时,cmake可能会使用老版本的gcc/g++
通过 which gccgcc/g++ --version 确定正确版本路径后,在cmake命令时加入对应gcc和g++的位置:

1
cmake .. -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++

重要指令

  • add_library - 生成库文件

    1
    add_library(libname [SHARED|STATIC] ${SRC})
  • add_compile_options - 添加编译参数

    1
    add_compile_options(-Wall -std=c++11 -O2)
  • add_executable - 生成可执行文件

    1
    add_executable(main main.cpp test.cpp)
  • add_subdirectory - 向工程添加存放源文件的子目录,其中需有一个CMakeLists.txt

    1
    add_subdirectory(src)
  • include_directories - 引入头文件目录

  • link_directories - 引入库目录,如工程编译时可能用到第三方库的 lib 文件

  • link_libraries - 引入库文件到当前工程(全路径)

  • target_link_libraries - 引入库文件到子工程,即分配,故需指定子工程

    1
    target_link_libraries(子工程名 库文件1 库文件2 ...)
  • target_include_directories - 引入头文件目录到子工程,同5

编译工程

1
2
3
4
vim CMakeLists.txt
mkdir build && cd build
cmake ..
make