配置主程序:
本地输出目录:"$(ProjectDir)bin\$(Platform)\$(Configuration)\"修改为"$(ProjectDir)..\bin\$(Platform)\$(Configuration)\",是为了将所有项目输出文件放到同一个目录中,方便相互引用。
目标文件扩展名:".out"修改为"",是为了不生成文件后缀,一般的Linux可执行程序是没有扩展名称的,可修改也可不修改。
远程生成根目录:"~/projects"修改为"/root/projects/$(SolutionName)","~"和"/root"是等价的,但是运行时动态库搜索目录不支持~路径,添加“$(SolutionName)”是为了区分不同的解决方案下相同名称的项目。
远程生成项目目录:"~/projects"修改为"/root/projects/$(SolutionName)","~"和"/root"是等价的,但是运行时动态库搜索目录不支持~路径,添加“$(SolutionName)”是为了区分不同的解决方案下相同名称的项目。
配置动态库:"$(RemoteRootDir)/$(ProjectName)"
本地输出目录:"$(ProjectDir)bin\$(Platform)\$(Configuration)\"修改为"$(ProjectDir)..\bin\$(Platform)\$(Configuration)\"
目标文件扩展名:".out"修改为".so"
远程生成根目录:"~/projects"修改为"/root/projects/$(SolutionName)"
配置类型:"应用程序(.out)"修改为"动态库(.so)"
配置静态库:
本地输出目录:"$(ProjectDir)bin\$(Platform)\$(Configuration)\"修改为"$(ProjectDir)..\bin\$(Platform)\$(Configuration)\"
目标文件扩展名:".out"修改为".a"
远程生成根目录:"~/projects"修改为"/root/projects/$(SolutionName)"
配置类型:"应用程序(.out)"修改为"动态库(.a)"
修改工作目录为执行程序同级目录
一般默认即可
静态库时需要指定:
作为库的时候需要指定:
上面的参数配置最终组合生成了命令行,也可以在下面“其他选项”补充
附加库目录:在"%(AdditionalLibraryDirectories)"前面添加"$(RemoteRootDir)/bin/$(Platform)/$(Configuration);",这个是远程主机CentOS上的路径,相当于gcc编译时指定"-L[路径]"选项,用于指定引用动态库和静态库的目录;
库依赖项:添加"dynamic_library;static_library",相当于gcc设置"-l[库名称]"选项,用于指定链接时所需要的动态库和静态库名称,如果找不到依赖的库文件,链接时会错误,显示"无法解析的符号"。
其他选项:添加"-Wl,-rpath=$(RemoteRootDir)/bin/$(Platform)/$(Configuration) ",指定程序运行时搜索动态库的路径。
/*********************************************************************************
* Copyright 2019 Huawei Technologies Co.,Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
**********************************************************************************
*/
#ifndef ESDKOBS_H
#define ESDKOBS_H
#include
#if defined __GNUC__ || defined LINUX
#include
#else
#include
#endif
#ifdef WIN32
#ifdef OBS_EXPORTS
#define eSDK_OBS_API __declspec(dllexport)
#else
#define eSDK_OBS_API __declspec(dllimport)
#endif
#else
#define eSDK_OBS_API __attribute__((__visibility__("default")))
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define OBS_INIT_WINSOCK 1
#define OBS_INIT_ALL (OBS_INIT_WINSOCK)
#define OBS_MAX_DELETE_OBJECT_NUMBER 1000
#define OBS_MAX_DELETE_OBJECT_DOC 1024000
eSDK_OBS_API void compute_md5(const char *buffer, int64_t buffer_size, char *outbuffer);
eSDK_OBS_API int set_obs_log_path(const char *log_path);
eSDK_OBS_API void set_openssl_callback(obs_openssl_switch switch_flag);
#ifdef __cplusplus
}
#endif
#endif /* LIBOBS_H */
ini跨平台库,iniparser-3.1
m_bReSendTovms = iniparser_getint(RecordIni, "LiveSetting:ReSendToVMS", 1);
strRecPath = iniparser_getstring(RecordIni, "RecordServer:RecordPath", "/mnt");
需要注意:最后一个字段需要有换行符,不然读取可能失败。
ini文件需要设定格式为UTF-8;与Windows下的文件格式不同,使用GetPrivateProfileInt读取ini文件,格式必须为ANSI;
其中long类型和指针类型需要特别注意,编写跨平台的软件时尽量不要使用long类型,或者需要对long类型做特殊处理。GUID的定义需要注意
在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可通过三种方法来指定:方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径;方法二:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径;方法三:在编译目标代码时指定该程序的动态库搜索路径。
众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库,并且该动 态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函数,以及该动态库的其它资源了。在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定。
通过gcc参数指定
-Wl,-rpath=${LD_PATH} #-Wl,-rpath=<动态库所在路径>
g++ ${RPATH} ./opencv_knn.cpp -o knn
通过gcc参数制定之后就不需要配置环境变量和配置文件了。
通过设置环境变量
export LD_LIBRARY_PATH=/root/code/opencv/opencv-3.2.0/build/build/lib
#LD_LIBRARY_PATH=<动态库所在位置>
只对当前shell有效,关闭shell或者退出当前用户则环境变量配置及无效了。
export LD_LIBRARY_PATH=/root/code/opencv/opencv-3.2.0/build/build/lib
通过配置文件
修改/etc/ld.so.conf文件。
其文件内容为:
[root@VM_24_16_centos etc]# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
[root@VM_24_16_centos etc]#
所以,可以在文件夹/etc/ld.so.conf.d/中添加自己的文件,例如:创建文件gx.conf,
然后在文件中添加动态库路径,例如:
/root/code/opencv/opencv-3.2.0/build/build/lib
注意,保存退出之后需要执行命令ldconfig刷新当前缓存。
使用附加依赖项的模式:
ldconfig的方式
gcc指定参数-WL,rpath=.
readelf -d xxx
#!/bin/bash
echo "InstallRecordServer Begin"
echo $PWD>librecordserver-x86_64.conf
sudo cp librecordserver-x86_64.conf /etc/ld.so.conf.d/
ls /etc/ld.so.conf.d/librecordserver-x86_64.conf
sudo ldconfig
chmod +x recordServer
chmod +x startRecordServer.sh
chmod +x stopRecordServer.sh
sudo systemctl disable firewalld
echo -e "* soft nofile 40960\n* hard nofile 81920" | sudo tee -a /etc/security/limits.conf
#非root用户执行失败
sudo ulimit -n 81920
echo "InstallRecordServer End"
Windows编写的脚本在Linux执行可能遇到问题:“/bin/bash^M: bad interpreter”
脚本格式需要设置为UNIX.
vi filename打开文件,执行 : set ff=unix 设置文件为unix,然后执行:wq,保存成unix格式。
vi filename打开文件,执行 : set ff,如果文件为dos格式在显示为fileformat=dos,如果是unxi则显示为fileformat=unix
#!/bin/bash
echo "RecordServer Begin"
./recordServer &
echo "RecordServer End"
#!/bin/bash
echo "StopRecordServer Begin"
sp_pid=`ps -ef | grep recordServer | grep -v grep | awk '{print $2}'`
if [ -z "$sp_pid" ];
then
echo "[ not find recordServer pid ]"
else
echo "find result: $sp_pid "
kill $sp_pid
fi
echo "StopRecordServer End"
rm -f recordServer
cp -r Release recordServer
tar -zcvf recordServer.tar.gz --exclude=recordServer/RecLogInfo --exclude=recordServer/recordServer.log --exclude=recordServer/libCameraRecordInfo.a recordServer
什么是rpm包?
rpm 相当于windows中的安装文件,它会自动处理软件包之间的依赖关系。
rpm优点:
包管理系统简单,通过几个命令就可以实现包的安装、升级、卸载。
安装速度比源码包快的多。
流程:
打rpm 包需要的东西有 源码、spec文件(打rpm包的脚本)、rpmbuild工具。
1. 安装rpmbuild
$yum install rpmbuild
$yum install rpmdevtools
$rpmdev-setuptree
此时rpmbuild已经安装好了,可以查看一下
rpmbuild --showrc | grep topdir
把这个包拷贝出来,发给其他机器,就可以使用rpm -ivh 安装了
制作一个简单的rpm包:helloworld
静态库提示-fPIC的例子
编译的时候可以编译成功, 但是当调试的时候会报这个错
防火墙关闭的例子
uname -n
rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具。优点就是不用再开一个sftp工具登录上去上传下载文件。
sz:将选定的文件发送(send)到本地机器
rz:运行该命令会弹出一个文件选择窗口,从本地选择文件上传到Linux服务器
安装命令:
yum install lrzsz
从服务端发送文件到客户端:
sz filename
从客户端上传文件到服务端:
rz
在弹出的框中选择文件,上传文件的用户和组是当前登录的用户
SecureCRT设置默认路径:
Options -> Session Options -> Terminal -> Xmodem/Zmodem ->Directories
Xshell设置默认路径:
右键会话 -> 属性 -> ZMODEM -> 接收文件夹
sudo mount -t cifs -o username="user",password="pwd",
uid=1001,gid=1001,dir_mode=0775,file_mode=0664,nounix,
noserverino //192.168.1.xxx/CVR ~/projects/cvr_win/
或者Windows挂载Linux
[csvtest@ecs-395b ~]$ yum -y install gcc
# yum -y install gcc-c++
# yum install make
# gcc -v
# gcc --version
[csvtest@ecs-395b ~]$ yum search sz
Loaded plugins: fastestmirror
Determining fastest mirrors
* base: mirrors.huaweicloud.com
* epel: mirrors.yun-idc.com
* extras: mirrors.huaweicloud.com
* updates: mirrors.huaweicloud.com
======================================================================================================================== N/S matched: sz =========================================================================================================================
laszip-devel.aarch64 : The development files for laszip
lrzsz.aarch64 : The lrz and lsz modem communications programs
laszip.aarch64 : Quickly turns bulky LAS files into compant LAZ files
Name and summary matches only, use "search all" for everything.
yum源没有或者版本不够的情况,yum 默认安装的gcc版本为4.8.5
wget https://ftp.gnu.org/gnu/gcc/gcc-7.2.0/gcc-7.2.0.tar.gz
tar xzf gcc-7.2.0.tar.gz
cd gcc-7.2.0
./configure --with-system-zlib --disable-multilib --enable-languages=c,c++
make -j 8
make install
top
htop
ps -aux | grep zookeeper
top -p 10997
方法一:PS
在ps命令中,“-T”选项可以开启线程查看。下面的命令列出了由进程号为
ps -T -p
方法二: Top
top命令可以实时显示各个线程情况。要在top输出中开启线程查看,请调用top命令的“-H”选项,该选项会列出所有Linux线程。在top运行时,你也可以通过按“H”键将线程查看模式切换为开或关。
top -H
要让top输出某个特定进程
top -H -p
方法三: Htop
一个对用户更加友好的方式是,通过htop查看单个进程的线程,它是一个基于ncurses的交互进程查看器。该程序允许你在树状视图中监控单个独立线程。
要在htop中启用线程查看,请开启htop,然后按
ls -l /proc/184172/fd/* | wc -l
ls -l /proc/184172/fd/* |more
lsof -p 184172
ulimit –a
ore file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 29238
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 29238
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
ulimit -n 2000
这个命令可以把默认的句柄数改为2000,但系统重启后会恢复默认值
这个文件在系统中的默认值配置在/etc/security/limits.conf文件中,加入以下配置:
修改了/etc/security/limits.conf ,必须要重启,才能生效。
* soft nofile 2000
* hard nofile 2000
下面是red hat/CentOs7关闭防火墙的命令!
1:查看防火状态
systemctl status firewalld
service iptables status
2:暂时关闭防火墙
systemctl stop firewalld
service iptables stop
3:永久关闭防火墙
systemctl disable firewalld
chkconfig iptables off
4:重启防火墙
systemctl enable firewalld
service iptables restart
pmap [pid]
# pmap -x 21407
21407: /root/projects/SVDSE/VsipTcpVideoProxy/../bin/x64/Debug/recordServer
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 60 48 8 r-x-- recordServer
000000000060e000 4 4 4 r---- recordServer
000000000060f000 4 4 4 rw--- recordServer
0000000000610000 264 204 204 rw--- [ anon ]
00007ffe98000000 65032 64776 64776 rw--- [ anon ]
00007ffe9bf82000 504 0 0 ----- [ anon ]
00007ffe9c000000 65032 2692 2692 rw--- [ anon ]
.........
00007ffff7dc8000 8 8 8 r---- libStorage.so
00007ffff7dca000 4 4 4 rw--- libStorage.so
00007ffff7dcb000 64 4 4 rw--- [ anon ]
00007ffff7ddb000 136 116 20 r-x-- ld-2.17.so
00007ffff7dfd000 2020 432 432 rw--- [ anon ]
00007ffff7ff6000 16 16 16 rw--- [ anon ]
00007ffff7ffa000 8 8 0 r-x-- [ anon ]
00007ffff7ffc000 4 4 4 r---- ld-2.17.so
00007ffff7ffd000 4 4 4 rw--- ld-2.17.so
00007ffff7ffe000 4 4 4 rw--- [ anon ]
00007ffffffde000 132 16 16 rw--- [ stack ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------- ------- -------
total kB 5578904 706776 703072
如何查看栈空间大小
对于 x86 和 x64 计算机,默认堆栈大小为 1 MB。在 Itanium 芯片组上,默认大小为 4 MB。linux下默认的堆栈空间大小是8M或10M,不同的发行版本可能不太一样。可以使用ulimit指令查看栈空间大小,指令ulimit -s或者ulimit -a如下图:
ulimit -s
查看栈空间大小,Linux下默认为8192KB
VIRT:virtual memory usage 虚拟内存
1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量
RES:resident memory usage 常驻内存
1、进程当前使用的内存大小,但不包括swap out
2、包含其他进程的共享
3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
4、关于库占用内存的情况,它只统计加载的库文件所占内存大小
SHR:shared memory 共享内存
1、除了自身进程的共享内存,也包括其他进程的共享内存
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
3、计算某个进程所占的物理内存大小公式:RES – SHR
4、swap out后,它将会降下来
DATA
1、数据占用的内存。如果top没有显示,按f键可以显示出来。
2、真正的该程序要求的数据空间,是真正在运行中要使用的。
top 运行中可以通过 top 的内部命令对进程的显示方式进行控制。内部命令如下:
s – 改变画面更新频率
l – 关闭或开启第一部分第一行 top 信息的表示
t – 关闭或开启第一部分第二行 Tasks 和第三行 Cpus 信息的表示
m – 关闭或开启第一部分第四行 Mem 和 第五行 Swap 信息的表示
N – 以 PID 的大小的顺序排列表示进程列表
P – 以 CPU 占用率大小的顺序排列进程列表
M – 以内存占用率大小的顺序排列进程列表
h – 显示帮助
n – 设置在进程列表所显示进程的数量
q – 退出 top
s – 改变画面更新周期
tar语法
压缩
tar -czvf ***.tar.gz
tar -cjvf ***.tar.bz2
解压缩
tar -xzvf ***.tar.gz
tar -xjvf ***.tar.bz2
tar [主选项+辅选项] 文件或目录
主选项是必须要有的,它告诉tar要做什么事情。
辅选项是辅助使用的,可以选用。
tar常用命令:
主选项:
-x 从档案文件中释放文件。
-c 创建新的档案文件。如果用户想备份一个目录或是一些文件,就要选择这个选项。
-r 把要存档的文件追加到档案文件的末尾。例如用户已经做好备份文件,又发现还有一个目录或
是一些文件忘 记备份了,这时可以使用该选项,将忘记的目录或文件追加到备份文件中。
-t 列出档案文件的内容,查看已经备份了哪些文件。
-u 更新文件。就是说,用新增的文件取代原备份文件,如果在备份文件中找不到要更新的文件,
则把它追加到备份文件的最后。
辅助选项:
-j 代表使用‘bzip2’程序进行文件的压缩 tar.bz2
-z 用gzip来压缩/解压缩文件,加上该选项后可以将档案文件进行压缩,但还原时也一定要使用该
选项进行解压缩。 tar.gz
-v 详细报告tar处理的文件信息。如无此选项,tar不报告文件信息。
-b 该选项是为磁带机设定的,其后跟一数字,用来说明区块的大小,系统预设值为20(20×512 bytes)。
-f 使用档案文件或设备,这个选项通常是必选的。
-k 保存已经存在的文件。例如把某个文件还原,在还原的过程中遇到相同的文件,不会进行覆盖。
-m 在还原文件时,把所有文件的修改时间设定为。
-M 创建多卷的档案文件,以便在几个磁盘中存放。
-w 每一步都要求确认。
tar包管理
1、tar包的创建
tar -cvf file.tar file1 file2
tar -zcvf file.tar.gz file1 file2
tar -jcvf file.tar.bz2 file1 file2
2、tar包的查看
tar -tvf file.tar
tar -ztvf file.tar.gz
tar -jtvf file.tar.bz2
3、释放tar包
tar -xvf file.tar
tar -zxvf file.tar.gz
tar -jxvf file.tar.bz2
补充一点 如果需要打包一个文件夹,但其中的几个文件不需要打包,命令如下
打包test文件夹 test里的 1 这个文件夹不需要打包
[root@localhost /]# cd /usr/test
[root@localhost test]# ls
1 2 3
返回/usr 目录
[root@localhost test]# cd /usr
[root@localhost usr]# tar -zcvf test.tar.gz --exclude=test/1 test
test/
test/3/
test/3/333.png
test/2/
test/2/222.png
果然没有打包test/1 文件夹
打包程序:tar
c: 创建文档
t: 列出存档内容
x:提取存档
f: filename 要操作的文档名
v:详细信息
z 用于gzip压缩: filename.tar.gz
j 用于bzip压缩: filename.tar.bz2
J 用于xz压缩: filename.tar.xz
将tar压缩文件解压到指定的目录下的命令是:
tar -xvf 压缩文件 -C /指定目录
例:#tar -xvf openstack_test.tar -C /tmp
说明:把根目录下的openstack_test.tar解压到/tmp下
ulimit -c unlimited
sysctl -p /etc/sysctl.conf
kill -s SIGSEGV 13425
调试core文件
gdb recordServer
core-file core_recordServer_13425
然后执行bt看堆栈信息
lsof -i:26000
netstat -tunlpc
用于显示tcp,udp的端口和进程等相关情况,如下图
命令里的t,u,n,l,p均有不同含义:
-t 仅显示和tcp相关的
-u 仅显示和udp相关的
-n 不限时别名,能显示数字的全部转换为数字
-l 仅显示出于Listen(监听)状态的
-p 显示建立这些连接的程序名
tcpdump -i eth0 tcp port 26000
tcpdump src host ip 抓取从该ip发来的信息
tcpdump src port 5070 抓取从5070发来的消息
tcpdump host ip and port 5070 抓取该ip&&端口
tcpdump host 192.168.1.101 and udp port 5060
tcpdump src host 192.168.1.101 and src port 5060 and udp
tcpdump -i enp1s0 port 5070 | grep MESSAGE
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。
不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
ANSI编码表示英文字符时用一个字节,表示中文用两个或四个字节。
在中文和日文操作系统里生成的(txt和xml)文件的编码虽然都是ansi,但是,在简体中文系统下,ansi 编码代表 GB2312 编码,在日文操作系统下,ansi 编码代表 JIS 编码。不同 ansi 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ansi 编码的文本中。
结论:国际文档(txt和xml)使用unicode编码是正宗做法;操作系统和浏览器都能够“理解”unicode编码。浏览器“迫于压力”才“理解”utf-8编码。但是,操作系统有时只认unicode编码。