西北地区基于3S技术野外地质工作管理与服务体系构建

西北地区基于3S技术野外地质工作管理与服务体系构建,第1张

中国地质调查局西安地质调查中心主要承担西北五省(区)地质调查及相关综合研究工作。西北地区野外地质项目工作区多为高海拔、高山峡谷、戈壁、沙漠等自然环境极为恶劣的无人区,通讯条件有限,存在大量手机通讯、地面网络通信的盲区。目前,在通讯信号盲区,卫星电话、对讲机成为地质人员主要通讯设备。但卫星电话的推广应用受自动化程度低和成本高所限制,对讲机的应用受距离和山体阻碍的限制,很难满足野外地质工作人员的通信需求。急需通过高新技术为野外地质调查工作提供动态化管理和服务,为野外地质调查工作人员提高生命安全保障。

“基于3S技术的野外地质调查工作管理与服务关键技术研究与应用”是国土资源部公益性行业科研专项项目,中国地质调查局发展研究中心为总项目承担单位。在总项目的技术指导下,西北区3S 关键技术研究与应用课题组采用我国北斗一代卫星系统通讯与定位技术、网络技术、网格技术等先进的技术方法,积极开展了西北区野外地质工作管理与服务网格结点建设示范工作,组建基于北斗卫星通讯技术的野外地质调查工作信息网络,部署野外地质调查工作管理与服务系统。初步实现“野外人员-野外驻地-西安中心站”三级互联互通。为野外地质调查工作的管理与服务提供了信息化通道,加大了西安地质调查中心业务网的覆盖范围,从而增强了西安地质调查中心野外地质调查工作的管理能力和服务水平。通过在西安地质调查中心以及西宁、乌鲁木齐两个野外工作站等地的示范与应用,构建西北地区野外地质调查生产调度、突发事件、应急处置的远程服务网格结点体系和管理平台,为西北地区野外地质调查人员和管理人员提供了一体化的地质调查工作管理与服务的新模式,从而增强了西安地质调查中心、乌鲁木齐野外工作站、西宁野外工作站联动服务意识,全面提升公益性地质工作的综合管理能力和水平。

一、西北地区基于3S技术野外地质工作管理与服务体系结点组网与部署

西安中心野外地质工作管理与服务网格结点属于中国地质调查局二级网格结点,通过北斗卫星系统的无线通讯网络、中国地质调查局广域网的长途数字链路专线两条物理链路上链中国地质调查局中心结点,同时与西宁、乌鲁木齐两个野外工作站采用北斗卫星通讯,建立联动机制,实现“中国地质调查局-西安地质调查中心-野外工作站-野外驻地”四级互联互通,使得野外工作人员能与各级管理部门、服务站点之间保持实时通讯。野外地质工作管理与服务结点体系如图7-1所示。

图7-1 西北地区野外地质调查工作管理与服务体系

野外地质调查工作管理与服务网络结点系统与地质调查项目的管理与服务流程紧密结合,具备野外工作人员态势管理、路线示踪、就近人员查找、短信广播与群发、通讯与定位信息查询等功能,可为野外地质调查工作的质量监控、检查、管理和服务等各个环节提供野外地质调查、应急保障等多种信息数据的采集、传输、分享、处理、反馈和决策现代化的管理工具。

(一)北斗卫星通讯组两

野外地质调查工作的北斗卫星通讯组网架构总体由四级构成,分别为中国地质调查局中心结点、大区中心管理与服务结点、野外工作站、野外项目驻地。各级结点之间采用北斗一代卫星导航定位系统的通讯技术,实现互联互通,为野外地质调查工作的管理与服务提供高效、便捷的信息通道。

西北区北斗卫星通讯组网建设工作主要包括西安中心结点北斗中心式指挥机的部署、项目驻地级北斗普通型指挥机的部署以及用户级北斗蓝牙通讯与定位终端的调试。北斗卫星终端设备购置情况见表7-1,西北区北斗卫星通讯组网如图7-2a所示,北斗卫星通讯工作流程如图7-2b所示。

表7-1 北斗卫星终端设备购置情况表

图7-2a 北斗卫星通讯组网示意图

图7-2b 北斗卫星通讯工作流程图

北斗中心式指挥机安装于西安中心机房,上接北斗天线,用于接收北斗卫星通讯定位信息,下接服务器,负责存储北斗信息,负责西北区北斗用户终端信息的监控与管理,构成西北区野外地质调查工作管理与服务结点的主要硬件设备。北斗普通型指挥机,该设备数据安全性高、稳定性强、重量轻、体型小,适合于野外项目驻地使用。通过笔记本电脑或台式机的串口与之连接,配套使用。北斗蓝牙通讯定位模块属于用户级北斗终端设备,具备北斗短报文通信与定位功能,无显示屏,需通过无线蓝牙技术与PDA 掌上机或平板电脑配套使用,适合于野外地质调查工作人员使用。

(二)北斗通讯定位设备部署

1北斗中心式指挥机部署

北斗中心式指挥机(图7-3)为管理型用户机的高端产品,可对1000个北斗用户终端进行监控、管理。产品整机模块化设计,便于今后西北区北斗用户容量扩容及进行系统维护。在数据安全性、处理速度、稳定性等方面具有显著优势。

图7-3 北斗中心式指挥机

西北区北斗中心式指挥机安装于西安地质调查中心机房,负责西北区北斗用户终端信息的监控与管理,构成西北区野外地质调查工作管理与服务结点的主要硬件设备。具体部署如下:

2011年7月设备到位后,课题组组织并实施北斗中心式指挥机的安装与调试。其中北斗中心式指挥机的主机安装在西安地质调查中心机房(位于办公楼4层)。北斗中心式指挥机天线长25m,天线接收器固定于办公楼7楼楼顶(图7-4所示)。北斗中心式指挥机天线与正南方建筑物的仰角小于45°。部署完后,北斗一代卫星系统的三颗同步卫星(东星、西星、备份星)波束均能被北斗中心式指挥机接收,且信号稳定,短信和定位 *** 作的成功率达到95%以上(图7-5)。

图7-4 北斗中心式指挥机天线

图7-5 北斗卫星信号接收

北斗中心式指挥机硬件性能及技术参数如下:

1)监控、管理下属用户的数量可扩展到1000个;

2)具备北斗定位、通信功能;

3)可监控下属用户的通讯与定位信息;

4)具备短信广播与群发功能:

5)支持电子地图显示:

6)IC卡拆卸安装简便快捷;

7)内置数据服务器,集成12英寸加固显示器;

8)数据接口方式:RS232串口、网口;

9)整机采用2U 高度设计,可以直接安装架设到标准19英寸机柜中;

10)供电方式:交流220V、50Hz。

2北斗普通型指挥机部署

北斗普通型指挥机为管理型用户机,可对100个北斗终端用户进行监控、管理。该设备数据安全性高、稳定性强、重量轻、体型小,适合于野外项目驻地使用。但无显示屏,需通过笔记本电脑或台式机的串口与之连接,配套使用。北斗普通型指挥机示意图如图7-6所示。

图7-6 北斗普通型指挥机示意图

此次课题组购置北斗普通型指挥机1台,构成野外项目驻地级北斗卫星通讯组网设备。北斗普通型指挥机的架设十分便捷,l0 分钟之内即可架设完毕,图7-7为课题组在青海阿尔金1∶5万打柴沟6幅区调项目驻地部署的北斗普通型指挥机。

图7-7 野外驻地北斗普通指挥机部署

北斗普通型指挥机硬件性能与技术参数如下:

1)监控、管理下属的用户数量为100个;

2)具备北斗定位、通信功能:

3)具备监控下属用户定位、短信发送等功能;

4)支持电子地图显示;

5)数据接口方式:RS232串口:

6)整机采用1U高度设计,可直接安装架设到标准19英寸机柜中:

7)供电方式:交流:220V/50Hz或直流:9~32V。

3北斗蓝牙通讯定位终端部署

北斗蓝牙通讯定位终端属于用户级北斗终端设备,具备北斗短报文通信与定位功能,无显示屏,需通过无线蓝牙技术与PDA 掌上机或平板电脑配套使用,适合于野外地质调查工作人员使用。

此次北斗通讯组网示范,课题组从相关北斗运营公司购置34台北斗蓝牙通讯定位终端模块(图7-8)。

图7-8 北斗蓝牙通讯定位终端

课题组在西北区选择了4个野外地质调查项目进行北斗组网示范,其中区域地质调查类项目3个,地质灾害类项目1个。课题组与野外工作人员共同测试了北斗通讯的稳定性、定位的精确性,同时与基于我国卫星的野外地质调查应用高技术产业化示范工程项目组人员联合测试了不同北斗卫星供应商北斗终端设备之间的兼容性、联通性。

北斗蓝牙通讯定位终端主要特点、性能指标等参数如下。

(1)主要特点

1)具备北斗终端设备的定位与通信功能;

2)通过蓝牙连接PDA 掌上机或计算机,控制北斗终端的定位或通信进行无线数据的传输:

3)电池和IC 卡拆卸安装方便;

4)环境适应能力满足野外环境使用;

5)具备一键式平安报和危险报警功能。

(2)性能指标

1)接收灵敏度≤1×10-5(方位角0°~180°,仰角20°~50°,接收信号电平-1546dBW);

2)首捕时间≤2s;

3)重捕时间≤1s;

4)蓝牙传输距离≤10m。

(3)结构尺寸和重量

1)外形尺寸:整机长×宽×高:≤121mm×68mm×36mm(带包角尺寸);

2)重量:≤05kg;

3)接口:RS232接口、蓝牙接口。

(4)电源

1)待机功耗≤2W;

2)供电方式:内置电池;供电待机时间不少于10h。

二、管理与服务结点系统建设

野外地质调查工作管理与服务系统运行在基于现代化的北斗卫星通信技术、网络技术、网格技术等先进技术构建的通讯网络上。系统功能设计与地质调查业务流紧密结合,实现了西北区野外地质调查工作的远程管理与服务,改变了以往地质调查工作信息传递、数据交换的模式。系统平台总体分为三部分:部署于大区机房的GSIGrid北斗应急态势保障系统;部署于野外工作站或项目驻地的DGSS(2010)北斗信息监控模块;安装于野外地质人员掌上机的数字填图野外数据采集系统(RGM ap)北斗功能模块。野外地质调查工作管理与服务系统安装与部署的详细流程如下所述。

(一)GSIGrid北斗应急态势保障系统

西安地质调查中心GSIGrdi野外地质调查管理服务与安全保障系统内嵌于原有的中国地质调查信息网格平台西安结点中,通过网络访问北斗中心式指挥机,并对其下属卡的北斗信息进行实时监控和管理。可实现野外地质调查工作人员的态势管理,并实时获取野外项目进展情况。同时可利用中心结点丰富的数据资源,为野外工作人员提供查询服务,为突发事件应急处置的管理与决策提供数据支持。

GSIGird 北斗应急态势保障系统安装过程分两步实施:北斗信息数据库安装、北斗应急态势保障系统安装。安装与部署过程如下。

1北斗信息数据库安装

北斗信息数据库采用Oracle数据库,数据库版本为O racle1020。安装于北斗中心式指挥机上,安装过程如下。

(1)Oracle数据库安装

本次数据库采用O racle1020,安装与配置过程参考“O racle数据库安装手册”。

(2)北斗数据库导入

首先将BDServer文件夹拷贝到北斗中心式指挥机上,文件夹内容如图7-9所示。

图7-9 北斗数据库文件

运行BDServerexe,d出图7-10所示界面。

选择“数据库指令→数据库创建(O racle)”菜单,d出如图7-11所示对话框。

输入Oracle系统SYSTEM 用户的密码,输入创建的新的数据库的用户名称和用户密码,选择北斗信息数据库原型(dmp文件),点击“确定”按钮,进入DOS数据库导入界面,完成数据库导入。

(3)北斗数据库访问

数据库导入成功,d出数据库导入完成对话框。选择“连接设置→打开串口”菜单,d出如图7-12所示对话框。

图7-10 北斗数据库导入(1)

图7-11 北斗数据库导入(2)

图7-12 北斗数据库访问

串口设置为“串口2”,协议设置为“UART_40”;输入北斗信息数据库的用户名、用户密码和连接地址,点击“确定”d出如下对话框,完成北斗数据库部署工作。图7-13为北斗数据库运行界面,图7-14为北斗野外人员信息数据库管理界面。

2北斗应急态势保障系统安装

北斗应急态势保障系统主要包括实时监控(定位、通讯)人员信息查询、北斗历史信息(定位、通讯)查询、路线追踪、紧急搜救和交互通讯,路径分析等功能。2011年11月在总项目承担单位中国地调局发展研究中心的协助下,完成北斗应用态势保障系统的安装与调试工作,内嵌于中国地质调查信息网格平台西安结点中,所选服务器为曙光天阔620r。

北斗应急态势保障系统安装方法参考《GSIGrid 野外地质调查管理服务与安全保障系统部署手册》,以下介绍系统硬件性能、系统资源以及运行情况。

(1)系统性能

服务器CPU:Intel(R)Xeon(TM)CPU 320GHz;

图7-13 北斗数据库运行界面

图714 北斗野外人员信息数据库

服务器硬盘:希捷500G;

服务器内存:DDR3400GB;

服务器显卡,RADEON 7000 RADEON VE Family:

服务器网卡:Intel(R)PRO/1000M TNetworkConnection。

(2)系统资源

数据资源:地球基本数据(VritualEarthData)、中国省界瓦片数据(cliplineHDF)、Oracle数据库(beidoudmp);

站点资源:IGServer服务器、系统站点(VirtualEarthDotNet);

软件资源:O racle10g或以上版本O racle客户端/服务器、GSIGrid野外地质调查管理服务与安全保障系统-信息平台 BDServer、北斗应急保障系统站点配置工具MVEConfigGuide。

3北斗应急态势保障系统运行情况

北斗应急态势保障系统部署完成后,课题组人员对系统的各项功能进行了测试与示范。系统运行正常,以下为部分功能使用截图。图7-15是北斗应急态势保障系统管理界面,图7-16是西北区人员列表示意图,图7-17是北斗短信监控(应急救援示范),图7-18是北斗终端移动轨迹跟踪(柞水县境内)。

图7-15 北斗应急态势保障系统管理界面

图7-16 西北区人员列表示意图

图7-17 北斗短信监控(应急救援示范)

图7-18 北斗终端移动轨迹跟踪(柞水县境内)

(二)DGSS(2010)北斗信息监控模块部署

DGSS北斗信息监控模块集成于数字地质调查信息综合平台(DGSInfo),安装在服务器或笔记本电脑上,通过串口线连接北斗普通型指挥机,构成野外工作站或项目驻地级野外工作管理与服务结点的软件系统。同时具备北斗蓝牙模块的所有功能和北斗应急态势保障系统的部分功能。

课题组所选笔记本型号IBM T61,通过串口线连接北斗普通型指挥机,完成项目驻地级野外工作管理与服务结点系统建设工作。并通过在陕西秦岭山阳县、青海省门源县青石嘴地区矿产远景调查项目、青海 1∶25万巴什库尔干幅(J46C001001)、茫崖镇幅(J46C002001)区域地质调查(修测)项目、青海阿尔金1∶5万打柴沟6幅区调项目以及青海省玉树州称多县环境灾害项目的示范,测试了DGSS北斗信息监控模块的各项功能,以下详细介绍该系统部署流程及系统运行情况。

1运行环境

系统运行环境需要符合表7-2中的要求。

表7-2 系统运行环境需要符合的要求

2连接北斗设备

安装完DGSS北斗信息监控模块后,需通过串口方式连接笔记本电脑与北斗普通型指挥机。由于IBM T61不提供串口接口,课题组需要将串口转换为USB连接。具体 *** 作步骤如下:

1)安装USB串口线驱动程序;

2)打开北斗设备,将其通过USB 接口与PC 相连;

3)打开“设备管理器”(在“我的电脑”上点击右键或者在“控制面板”中找),按下图找到“USB SerialP ort”,设置其串口号(本次示范所选串口为COM 4),如图7-19所示。

图7-19 笔记本串口设置

3访问北斗普通指挥机

进入DGSInfo系统,依次选择菜单“北斗→打开串口”,选择所需连接北斗设备对应的串口号进行连接,本次组网示范课题组选择的端口为COM 4。点击“OK”进入DGSS北斗信息监控模块。如图7-20所示。

图7-20 连接北斗普通指挥机

4DGSS北斗功能应用情况

DG SS 北斗信息监控模块部署完后,课题组录入了野外示范人员信息数据库,并在4个野外示范项目所在工区,对系统各项功能进行了全面测试与示范。经测试,系统与西安中心结点之间通讯正常,能有效地监控其下属卡信息。图7-21至图7-23为系统运行部分截图。

图7-21 北斗普通指挥机用户信息库

图7-22 北斗普通指挥机DGSS系统运行界面

图7-23 北斗普通指挥机DGSS系统短信管理

(三)RGMap北斗功能模块部署

数字填图野外数据采集系统(RGMap)中的北斗功能适用于野外一线工作人员使用,运行于掌上机中。系统支持北斗蓝牙移动模块和大部分种类的北斗移动一体机(屏幕尺寸和 *** 作系统需达到要求),其中,北斗蓝牙模块通过蓝牙功能与程序连接,一体机中的北斗模块通过串口直接与程序连接。本次示范所配备的掌上机型号为合众思壮集思宝 M 758(图7-24)、Getac PS535FC-1(图7-25)。系统具体部署及应用情况如下。

图7-24 集思宝M758

图7-25 Getac PS535

1运行环境

RGMap系统运行介质为掌上机, *** 作系统为微软Window Mobile系列,屏幕尺寸应大于35英寸。由于各种机型的 *** 作系统与屏幕大小有所不同,RGMap适用于不同版本的 *** 作系统,课题组所选掌上机 *** 作系统版本如下;

1)W indows Mobile65,机型:集思宝M758:

2)W indows M obile62,机型:Getac PS535FC

RGMap程序安装:将RGMap(WM6)程序拷贝到掌上机中。由DGSInfo系统生成野外手图数据拷贝到掌上机的“M y Documents”目录下。具体 *** 作见《数字地质调查系统 *** 作指南(上册)(中册)》。

2连接北斗蓝牙模块

首先在掌上机上进入蓝牙程序设置界面,搜索对应北斗蓝牙模块的蓝牙号,然后进行蓝牙配对(北斗蓝牙模块的蓝牙配对密码为8个0),并为北斗蓝牙模块建立“发送端口”(即COM 端口),此COM 端口即为RGMap北斗功能模块访问北斗蓝牙模块的COM 串口。连接过程见图7-26。

图7-26 连接北斗蓝牙模块

连接北斗蓝牙模块时有如下两点需要注意:

1)建立COM 时,建议取消“安全连接”选项,否则使用过程中,容易出现蓝牙信号中断;

2)一个COM 端口只能连接一台北斗蓝牙模块,且不能删除此连接。因掌上机的COM端口数量有限,掌上机连接北斗蓝牙模块数量过多时,会造成无法建立“发送端口”的现象(解决办法为恢复掌上机 *** 作系统)。建议在掌上机背面贴上与之唯一对应的北斗蓝牙模块的蓝牙号,避免因混乱使用而造成无法建立“发送端口”。

3RGM ap北斗功能应用情况

在秦岭、青藏高原、新疆等地,课题组人员针对RGM ap的短报文收发、平安报、遇险警报、定位等其他北斗功能进行了全面测试与示范,熟练掌握了各项功能的应用技术。图7-27为RGM ap北斗模块实际应用的界面展示。

图7-27 ROMap北斗模块运行界面

运行模式
关于PHP目前比较常见的五大运行模式:
1)CGI(通用网关接口/ Common Gateway Interface)
2)FastCGI(常驻型CGI / Long-Live CGI)
3)CLI(命令行运行 / Command Line Interface)
4)Web模块模式(Apache等Web服务器运行的模式)
5)ISAPI(Internet Server Application Program Interface)
备注:在PHP53以后,PHP不再有ISAPI模式,安装后也不再有php5isapidll这个文件。要在IIS6上使用高版本PHP,必须安装FastCGI 扩展,然后使IIS6支持FastCGI。
11、CGI模式
CGI即通用网关接口(Common Gateway Interface),它是一段程序,通俗的讲CGI就象是一座桥,把网页和Web服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器的执行程序,再把服务器执行程序的结果返还给HTML页。CGI 的跨平台性能极佳,几乎可以在任何 *** 作系统上实现。CGI已经是比较老的模式了,这几年都很少用了。
每有一个用户请求,都会先要创建CGI的子进程,然后处理请求,处理完后结束这个子进程,这就是Fork-And-Execute模式。 当用户请求数量非常多时,会大量挤占系统的资源如内存,CPU时间等,造成效能低下。所以用CGI方式的服务器有多少连接请求就会有多少CGI子进程,子进程反复加载是CGI性能低下的主要原因。
如果不想把 PHP 嵌入到服务器端软件(如 Apache)作为一个模块安装的话,可以选择以 CGI 的模式安装。或者把 PHP 用于不同的 CGI 封装以便为代码创建安全的 chroot 和 setuid 环境。这样每个客户机请求一个PHP文件,Web服务器就调用phpexe(win下是phpexe,linux是php)去解释这个文件,然后再把解释的结果以网页的形式返回给客户机。 这种安装方式通常会把 PHP 的可执行文件安装到 web 服务器的 cgi-bin 目录。CERT 建议书 CA-9611 建议不要把任何的解释器放到 cgi-bin 目录。 这种方式的好处是把Web Server和具体的程序处理独立开来,结构清晰,可控性强,同时缺点就是如果在高访问需求的情况下,CGI的进程Fork就会成为很大的服务器负担,想 象一下数百个并发请求导致服务器Fork出数百个进程就明白了。这也是为什么CGI一直背负性能低下,高资源消耗的恶名的原因。
12、FastCGI模式
FastCGI是CGI的升级版本,FastCGI像是一个常驻 (long-live)型的 CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去 Fork 一次 (这是 CGI 最为人诟病的 fork-and-execute 模式)。
FastCGI是一个可伸缩地、高速地在>进程在运行过程中遇到逻辑错误, 比如除零, 空指针等等, 系统会触发一个软件中断
这个中断会以信号的方式通知进程, 这些信号的默认处理方式是结束进程
发生这种情况, 我们就认为进程崩溃了
进程崩溃后, 我们会希望知道它是为何崩溃的, 是哪个函数, 哪行代码引起的错误
另外, 在进程退出前, 我们还希望做一些善后处理, 比如把某些数据存入数据库, 等等
下面, 我会介绍一些技术来达成这两个目标
1 在core文件中查看堆栈信息
如果进程崩溃时, 我们能看到当时的堆栈信息, 就能很快定位到错误的代码
在 gcc 中加入 -g 选项, 可执行文件中便会包含调试信息 进程崩溃后, 会生成一个 core 文件
我们可以用 gdb 查看这个 core 文件, 从而知道进程崩溃时的环境
在调试阶段, core文件能给我们带来很多便利 但是在正式环境中, 它有很大的局限:
1 包含调试信息的可执行文件会很大 并且运行速度也会大幅降低
2 一个 core 文件常常很大, 如果进程频繁崩溃, 硬盘资源会变得很紧张
所以, 在正式环境中运行的程序, 不会包含调试信息
它的core文件的大小, 我们会把它设为0, 也就是不会输入core文件
在这个前提下, 我们如何得到进程的堆栈信息呢
2 动态获取线程的堆栈
c 语言提供了 backtrace 函数, 通过这个函数可以动态的获取当前线程的堆栈
要使用 backtrace 函数, 有两点要求:
1 程序使用的是 ELF 二进制格式
2 程序连接时使用了 -rdynamic 选项
-rdynamic可用来通知链接器将所有符号添加到动态符号表中, 这些信息比 -g 选项的信息要少得多
下面是将要用到的函数说明:
#include <execinfoh>
int backtrace(void buffer,int size);
用于获取当前线程的调用堆栈, 获取的信息将会被存放在buffer中, 它是一个指针列表。
参数 size 用来指定buffer中可以保存多少个void 元素。
函数返回值是实际获取的指针个数, 最大不超过size大小
注意: 某些编译器的优化选项对获取正确的调用堆栈有干扰,
另外内联函数没有堆栈框架; 删除框架指针也会导致无法正确解析堆栈内容;
char backtrace_symbols (void const buffer, int size)
把从backtrace函数获取的信息转化为一个字符串数组
参数buffer应该是从backtrace函数获取的指针数组,
size是该数组中的元素个数(backtrace的返回值) ;
函数返回值是一个指向字符串数组的指针, 它的大小同buffer相同
每个字符串包含了一个相对于buffer中对应元素的可打印信息
它包括函数名,函数的偏移地址, 和实际的返回地址
该函数的返回值是通过malloc函数申请的空间, 因此调用者必须使用free函数来释放指针
注意: 如果不能为字符串获取足够的空间, 函数的返回值将会为NULL
void backtrace_symbols_fd (void const buffer, int size, int fd)
与backtrace_symbols 函数具有相同的功能,
不同的是它不会给调用者返回字符串数组, 而是将结果写入文件描述符为fd的文件中,每个函数对应一行
3 捕捉信号
我们希望在进程崩溃时打印堆栈, 所以我们需要捕捉到相应的信号 方法很简单
#include <signalh>
void (signal(int signum,void( handler)(int)))(int);
或者: typedef void(sig_t) ( int );
sig_t signal(int signum,sig_t handler);
参数说明:
第一个参数signum指明了所要处理的信号类型,它可以是除了SIGKILL和SIGSTOP外的任何一种信号。
第二个参数handler描述了与信号关联的动作,它可以取以下三种值:
1 一个返回值为正数的函数的地址, 也就是我们的信号处理函数
这个函数应有如下形式的定义: int func(int sig); sig是传递给它的唯一参数。
执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。
当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。
2 SIGIGN, 忽略该信号
3 SIGDFL, 恢复系统对信号的默认处理。
返回值: 返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。

注意:
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,
直到信号处理函数执行完毕再重新调用相应的处理函数。
如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
在信号发生跳转到自定的handler处理函数执行后,系统会自动将此处理函数换回原来系统预设的处理方式,
如果要改变此 *** 作请改用sigaction()。
4 实例
下面我们实际编码, 看看具体如何在捕捉到信号后, 打印进程堆栈, 然后结束进程
#include <iostream>
#include <timeh>
#include <signalh>
#include <stringh>
#include <execinfoh>
#include <fcntlh>
#include <map>
using namespace std;
map<int, string> SIG_LIST;
#define SET_SIG(sig) SIG_LIST[sig] = #sig;
void SetSigList(){
SIG_LISTclear();
SET_SIG(SIGILL)//非法指令
SET_SIG(SIGBUS)//总线错误
SET_SIG(SIGFPE)//浮点异常
SET_SIG(SIGABRT)//来自abort函数的终止信号
SET_SIG(SIGSEGV)//无效的存储器引用(段错误)
SET_SIG(SIGPIPE)//向一个没有读用户的管道做写 *** 作
SET_SIG(SIGTERM)//软件终止信号
SET_SIG(SIGSTKFLT)//协处理器上的栈故障
SET_SIG(SIGXFSZ)//文件大小超出限制
SET_SIG(SIGTRAP)//跟踪陷阱
}
string& GetSigName(int sig){
return SIG_LIST[sig];
}
void SaveBackTrace(int sig){
//打开文件
time_t tSetTime;
time(&tSetTime);
tm ptm = localtime(&tSetTime);
char fname[256] = {0};
sprintf(fname, "core%d-%d-%d_%d_%d_%d",
ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
FILE f = fopen(fname, "a");
if (f == NULL){
exit(1);
}
int fd = fileno(f);
//锁定文件
flock fl;
fll_type = F_WRLCK;
fll_start = 0;
fll_whence = SEEK_SET;
fll_len = 0;
fll_pid = getpid();
fcntl(fd, F_SETLKW, &fl);
//输出程序的绝对路径
char buffer[4096];
memset(buffer, 0, sizeof(buffer));
int count = readlink("/proc/self/exe", buffer, sizeof(buffer));
if(count > 0){
buffer[count] = '\n';
buffer[count + 1] = 0;
fwrite(buffer, 1, count+1, f);
}
//输出信息的时间
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "Dump Time: %d-%d-%d %d:%d:%d\n",
ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
fwrite(buffer, 1, strlen(buffer), f);
//线程和信号
sprintf(buffer, "Curr thread: %d, Catch signal:%s\n",
pthread_self(), GetSigName(sig)c_str());
fwrite(buffer, 1, strlen(buffer), f);
//堆栈
void DumpArray[256];
int nSize = backtrace(DumpArray, 256);
sprintf(buffer, "backtrace rank = %d\n", nSize);
fwrite(buffer, 1, strlen(buffer), f);
if (nSize > 0){
char symbols = backtrace_symbols(DumpArray, nSize);
if (symbols != NULL){
for (int i=0; i<nSize; i++){
fwrite(symbols[i], 1, strlen(symbols[i]), f);
fwrite("\n", 1, 1, f);
}
free(symbols);
}
}
//文件解锁后关闭, 最后终止进程
fll_type = F_UNLCK;
fcntl(fd, F_SETLK, &fl);
fclose(f);
exit(1);
}
void SetSigCatchFun(){
map<int, string>::iterator it;
for (it=SIG_LISTbegin(); it!=SIG_LISTend(); it++){
signal(it->first, SaveBackTrace);
}
}
void Fun(){
int a = 0;
int b = 1 / a;
}
static void ThreadFun(void arg){
Fun();
return NULL;
}
int main(){
SetSigList();
SetSigCatchFun();
printf("main thread id = %d\n", (pthread_t)pthread_self());
pthread_t pid;
if (pthread_create(&pid, NULL, ThreadFun, NULL)){
exit(1);
}
printf("fun thread id = %d\n", pid);
for(;;){
sleep(1);
}
return 0;
}
文件名为 btcpp
编译: g++ btcpp -rdynamic -I /usr/local/include -L /usr/local/lib -pthread -o bt
主线程创建了 fun 线程, fun 线程有一个除零错误, 系统抛出 SIGFPE 信号
该信号使 fun 线程中断, 我们注册的 SaveBackTrace 函数捕获到这个信号, 打印相关信息, 然后终止进程
在输出的core文件中, 我们可以看到简单的堆栈信息
5 善后处理
在上面的例子中, fun 线程被 SIGFPE 中断, 转而执行 SaveBackTrace 函数
此时, main 线程仍然在正常运行
如果我们把 SaveBackTrace 函数最后的 exit(1); 替换成 for(;;)sleep(1);
main 线程就可以一直正常的运行下去
利用这个特点, 我们可以做很多其它事情
游戏的服务器进程常常有这些线程:
网络线程, 数据库线程, 业务处理线程 引发逻辑错误的代码常常位于业务处理线程
而数据库线程由于功能稳定, 逻辑简单, 是十分强壮的
那么, 如果业务处理线程有逻辑错误, 我们捕捉到信号后, 可以在信号处理函数的最后,
通知数据库线程保存游戏数据
直到数据库线程把游戏信息全部存入数据库, 信号处理函数才返回
这样, 服务器宕机不会导致回档, 损失被大大降低
要实现这个机制, 要求数据库模块和业务处理模块具有低耦合度
当然, 实际应用的时候, 还有许多细节要考虑
比如, 业务处理线程正在处理玩家的数据, 由于发生不可预知的错误, 玩家的数据被损坏了, 这些玩家的数据就不应该被存入数据库


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zz/13104753.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-30
下一篇 2023-05-30

发表评论

登录后才能评论

评论列表(0条)

保存