Cgroup
进程绑核
1 | cd /sys/fs/cgroup/cpuset |
Linux Cgroup系列(04):限制cgroup的内存使用
火焰图生成与解析
- 环境准备
1 | # 安装 Linux 系统的 perf 工具 |
- 数据采样,解析生成火焰图
1 | perf record -a -g -F99 --call-graph dwarf -p <pid> sleep 30 |
- 常用命令
1 | -p <pid>:指定待分析进程的 pid(多个用,分隔列表) |
- 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 :8080fdisk创建和维护分区表tcpdump抓包route查看路由pgrep dummy查看进程号,-l显示进程名pkill dummyKill进程名,-f全匹配command lineps aux | grep -w 'hello' | grep -v grep | awk '{print $2}' | xargs kill -9cmd1 | xargs -I {} cmd2 {}将 cmd1 的每行输出作为 cmd2 的输入,{}仅作为占位符,换成如$均可
文件操作
sed -i "s/查找字段/替换字段/g" a.txtawk -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 | scp /home/web_server/mazhuang/load.sh web_server@${host}:/home/web_server/mazhuang/ |
Kill进程
1 | pkill -f $directory/dummy |
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断点的原理:
- 断点替换:在指定的地址处,GDB 会替换原有的指令为
int 3中断指令。当程序执行到该位置时,会产生一个中断信号。GDB 捕获信号后,会停止程序进入调试模式。- 保存原指令: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 gcc 和 gcc/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 | vim CMakeLists.txt |