golang中程序关闭触发哪个事件您好,在Golang中,当程序关闭时,会触发一个名为os.Exit的事件 。os.Exit是Go语言标准库中的一个函数,它可以接受一个整数参数,用来指定程序的退出状态 。当程序调用os.Exit时,它会立即终止程序的执行,而不会执行defer函数 。os.Exit函数会触发一个特殊的事件,可以让程序在退出前做一些必要的清理工作,比如关闭文件句柄,释放系统资源等 。此外,os.Exit函数还可以用来控制程序的退出状态 , 从而可以更好地控制程序的执行流程 。
Go语言基础语法(一)本文介绍一些Go语言的基础语法 。
先来看一个简单的go语言代码:
go语言的注释方法:
代码执行结果:
下面来进一步介绍go的基础语法 。
go语言中格式化输出可以使用 fmt 和 log 这两个标准库,
常用方法:
示例代码:
执行结果:
更多格式化方法可以访问中的fmt包 。
log包实现了简单的日志服务 , 也提供了一些格式化输出的方法 。
执行结果:
下面来介绍一下go的数据类型
下表列出了go语言的数据类型:
int、float、bool、string、数组和struct属于值类型,这些类型的变量直接指向存在内存中的值;slice、map、chan、pointer等是引用类型,存储的是一个地址 , 这个地址存储最终的值 。
常量是在程序编译时就确定下来的值,程序运行时无法改变 。
执行结果:
执行结果:
Go 语言的运算符主要包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符以及指针相关运算符 。
算术运算符:
关系运算符:
逻辑运算符:
位运算符:
赋值运算符:
指针相关运算符:
下面介绍一下go语言中的if语句和switch语句 。另外还有一种控制语句叫select语句,通常与通道联用,这里不做介绍 。
if语法格式如下:
if ... else :
else if:
示例代码:
语法格式:
另外 , 添加 fallthrough 会强制执行后面的 case 语句,不管下一条case语句是否为true 。
示例代码:
执行结果:
下面介绍几种循环语句:
执行结果:
执行结果:
也可以通过标记退出循环:
--THE END--
Go 语言的错误处理机制是一个优秀的设计吗这个问题说来话长 , 我先表达一下我的观点,Go语言从语法层面提供区分错误和异常的机制是很好的做法,比自己用单个返回值做值判断要方便很多 。
上面看到很多知乎大牛把异常和错误混在一起说 , 有认为Go没有异常机制的,有认为Go纯粹只有异常机制的,我觉得这些观点都太片面了 。
具体对于错误和异常的讨论 , 我转发一下前阵子写的一篇日志抛砖引玉吧 。
============================
最近连续遇到朋友问我项目里错误和异常管理的事情,之前也多次跟团队强调过错误和异常管理的一些概念 , 所以趁今天有动力就赶紧写一篇Go语言项目错误和异常管理的经验分享 。
首先我们要理清:什么是错误、什么是异常、为什么需要管理 。然后才是怎样管理 。
错误和异常从语言机制上面讲,就是error和panic的区别 , 放到别的语言也一样,别的语言没有error类型,但是有错误码之类的,没有panic,但是有throw之类的 。
在语言层面它们是两种概念,导致的是两种不同的结果 。如果程序遇到错误不处理,那么可能进一步的产生业务上的错误,比如给用户多扣钱了,或者进一步产生了异常;如果程序遇到异常不处理,那么结果就是进程异常退出 。
在项目里面是不是应该处理所有的错误情况和捕捉所有的异常呢?我只能说,你可以这么做,但是估计效果不会太好 。我的理由是:
如果所有东西都处理和记录,那么重要信息可能被淹没在信息的海洋里 。
不应该处理的错误被处理了,很容易导出BUG暴露不出来,直到出现更严重错误的时候才暴露出问题,到时候排查就很困难了,因为已经不是错误的第一现场 。
所以错误和异常最好能按一定的规则进行分类和管理,在第一时间能暴露错误和还原现场 。
对于错误处理,Erlang有一个很好的概念叫速错,就是有错误第一时间暴露它 。我们的项目从Erlang到Go一直是沿用这一设计原则 。但是应用这个原则的前提是先得区分错误和异常这两个概念 。
错误和异常上面已经提到了,从语言机制层面比较容易区分它们,但是语言取决于人为,什么情况下用错误表达,什么情况下用异常表达,就得有一套规则,否则很容易出现全部靠异常来做错误处理的情况 , 似乎Java项目特别容易出现这样的设计 。
这里我先假想有这样一个业务:游戏玩家通过购买按钮,用铜钱购买宝石 。
在实现这个业务的时候,程序逻辑会进一步分化成客户端逻辑和服务端逻辑,客户端逻辑又进一步因为设计方式的不同分化成两种结构:胖客户端结构、瘦客户端结构 。
胖客户端结构,有更多的本地数据和懂得更多的业务逻辑,所以在胖客户端结构的应用中,以上的业务会实现成这样:客户端检查缓存中的铜钱数量,铜钱数量足够的时候购买按钮为可用的亮起状态,用户点击购买按钮后客户端发送购买请求到服务端;服务端收到请求后校验用户的铜钱数量 , 如果铜钱数量不足就抛出异常 , 终止请求过程并断开客户端的连接 , 如果铜钱数量足够就进一步完成宝石购买过程 , 这里不继续描述正常过程 。
因为正常的客户端是有一步数据校验的过程的,所以当服务端收到不合理的请求(铜钱不足以购买宝石)时 , 抛出异常比返回错误更为合理,因为这个请求只可能来自两种客户端:外挂或者有BUG的客户端 。如果不通过抛出异常来终止业务过程和断开客户端连接,那么程序的错误就很难被第一时间发现,攻击行为也很难被发现 。
我们再回头看瘦客户端结构的设计,瘦客户端不会存有太多状态数据和用户数据也不清楚业务逻辑,所以客户端的设计会是这样:用户点击购买按钮 , 客户端发送购买请求;服务端收到请求后检查铜钱数量 , 数量不足就返回数量不足的错误码 , 数量足够就继续完成业务并返回成功信息;客户端收到服务端的处理结果后,在界面上做出反映 。
在这种结构下,铜钱不足就变成了业务逻辑范围内的一种失败情况,但不能提升为异常,否则铜钱不足的用户一点购买按钮都会出错掉线 。
所以,异常和错误在不同程序结构下是互相转换的,我们没办法一句话的给所有类型所有结构的程序一个统一的异常和错误分类规则 。
但是,异常和错误的分类是有迹可循的 。比如上面提到的痩客户端结构,铜钱不足是业务逻辑范围内的一种失败情况 , 它属于业务错误,再比如程序逻辑上尝试请求某个URL,最多三次,重试三次的过程中请求失败是错误 , 重试到第三次,失败就被提升为异常了 。
所以我们可以这样来归类异常和错误:不会终止程序逻辑运行的归类为错误,会终止程序逻辑运行的归类为异常 。
因为错误不会终止逻辑运行,所以错误是逻辑的一部分,比如上面提到的瘦客户端结构,铜钱不足的错误就是业务逻辑处理过程中需要考虑和处理的一个逻辑分支 。而异常就是那些不应该出现在业务逻辑中的东西 , 比如上面提到的胖客户端结构 , 铜钱不足已经不是业务逻辑需要考虑的一部分了,所以它应该是一个异常 。
错误和异常的分类需要通过一定的思维训练来强化分类能力,就类似于面向对象的设计方式一样的 , 技术实现就摆在那边 , 但是要用好需要不断的思维训练不断的归类和总结,以上提到的归类方式希望可以作为一个参考,期待大家能发现更多更有效的归类方式 。
接下来我们讲一下速错和Go语言里面怎么做到速错 。
速错我最早接触是在做的时候就体验到的,当然跟Erlang的速错不完全一致,那时候也没有那么高大上的一个名字,但是对待异常的理念是一样的 。
在.NET项目开发的时候 , 有经验的程序员都应该知道,不能随便re-throw,就是catch错误再抛出,原因是异常的第一现场会被破坏,堆栈跟踪信息会丢失,因为外部最后拿到异常的堆栈跟踪信息 , 是最后那次throw的异常的堆栈跟踪信息;其次 , 不能随便try catch,随便catch很容易导出异常暴露不出来,升级为更严重的业务漏洞 。
到了Erlang时期,大家学到了速错概念,简单来讲就是:让它挂 。只有挂了你才会第一时间知道错误,但是Erlang的挂 , 只是Erlang进程的异常退出,不会导致整个Erlang节点退出,所以它挂的影响层面比较低 。
在Go语言项目中 , 虽然有类似Erlang进程的Goroutine,但是Goroutine如果panic了,并且没有recover,那么整个Go进程就会异常退出 。所以我们在Go语言项目中要应用速错的设计理念,就要对Goroutine做一定的管理 。
在我们的游戏服务端项目中,我把Goroutine按挂掉后的结果分为两类:1、挂掉后不影响其他业务或功能的;2、挂掉后业务就无法正常进行的 。
第一类Goroutine典型的有:处理各个玩家请求的Goroutine,因为每个玩家连接各自有一个Goroutine,所以挂掉了只会影响单个玩家 , 不会影响整体业务进行 。
第二类Goroutine典型的有:数据库同步用的Goroutine,如果它挂了,数据就无法同步到数据库,游戏如果继续运行下去只会导致数据回档 , 还不如让整个游戏都异常退出 。
这样一分类,就可以比较清楚哪些Goroutine该做recover处理,哪些不该做recover处理了 。
那么在做recover处理时,要怎样才能尽量保留第一现场来帮组开发者排查问题原因呢?我们项目中通常是会在最外层的recover中把错误和堆栈跟踪信息记进日志 , 同时把关键的业务信息,比如:用户ID、来源IP、请求数据等也一起记录进去 。
为此,我们还特地设计了一个库 , 用来格式化输出堆栈跟踪信息和对象信息,项目地址:funny/debug · GitHub
通篇写下来发现比我预期的长很多,所以这里我做一下归纳总结,帮组大家理解这篇文章所要表达的:
错误和异常需要分类和管理,不能一概而论
错误和异常的分类可以以是否终止业务过程作为标准
错误是业务过程的一部分,异常不是
不要随便捕获异常,更不要随便捕获再重新抛出异常
Go语言项目需要把Goroutine分为两类 , 区别处理异常
在捕获到异常时 , 需要尽可能的保留第一现场的关键数据
以上仅为一家之言,抛砖引玉,希望对大家有所帮助 。
go语言--Goroutines1、goroutine:在go语言中 , 每一个并发的执行单元叫做goroutine,如果一个程序中包含多个goroutine,对两个函数的调用则可能发生在同一时刻
2、main goroutine:当一个程序启动时,其主函数即在一个单独的goroutine中运行,我们叫他为main gorountine
3、go goroutine:新的goroutine会用go语句来创建 , go 函数名,go语句会使其语句中的函数在一新创建的goroutine中运行,而go语句本身会迅速地完成
4、goroutine的退出:主函数返回时,所有的goroutine都会被直接打断,程序退出,除了从主函数退出或者终止程序之外,没有其他方法能够让一个goroutine来打断另一个的执行,但是可以通过另一种方式来实现这个目的 , 通过goroutine之间的通信来让一个goroutine请求其他的goroutine,并让请求的goroutine自行结束执行
应用程序池 'DefaultAppPool' 被自动禁用 , 原因是为此应用程序池提供服务的进程中出现一系列错误 。为应用程序池 'DefaultAppPool' 提供服务的进程意外终止 。进程 ID 是 '3056' 。进程退出代码是 '0xffffffff' 。
有关更多信息,请参阅在的帮助和支持中心 。
-----------------------------------
解决方法,给NETWORK SERVICE 加上访问iis服务的权限 , 具体方法如下:
-----------------------------------
点击“开始”-“控制面板”-“管理工具”-“组件服务”-“计算机”-“我的电脑”-“DCOM”选项,
选择其下的“IIS ADMIN SERVICE”,右健选择“属性”,找到“安全”,在“启动和激活权限”中编辑“自定义”,添加帐号“NETWORK SERVICE ”,
给该帐号赋予“本地启动”和“本地激活”的权限 , 重新启动IIS(点“开始”-“运行”-“CMD”,点确定 , 然后运行IISRESET),
之后再访问同一站点 , 则一切正常 。
另一解决方案:
事件类型: 警告
事件来源: W3SVC
事件种类: 无
事件 ID: 1009
日期: 2007-8-XX
事件: XX:XX:XX
用户: XX
计算机: XXXX
描述:
为应用程序池 'XXXXX' 提供服务的进程意外终止 。进程 ID 是 'XXXX' 。进程退出代码是 '0x80' 。
有关更多信息,请参阅在的帮助和支持中心 。
原因:
CAUSE
Together with each worker process that IIS creates under a separate identity, the system creates a new desktop object by allocating memory from the configured desktop heap. This issue occurs because, when that heap has been exhausted, IIS cannot create more worker processes. Clients then receive the "service unavailable" error message in their Web browsers when they try to visit Web sites that those application pools host.
独立进程的 内存堆戋消耗完了 , IIS不能创建更多的进程工作空间来处理
解决方法:
警告:需要修改服务器的注册表,请修改前备份相关键值
add the UseSharedWPDesktop registry key to your computer that is running IIS. This registry key permits all worker processes to run in one shared desktop, regardless of their worker process identities.
To add the UseSharedWPDesktop registry key:
1. HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC
2. 在Parameters键下新建一个DWORD项,名字为:UseSharedWPDesktop 值为1 重启IIS
MS关于此键值描述:
UseSharedWPDesktop
注册表路径:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters
数据类型:REG_DWORD
默认值: 0
范围: 0 - 1
如果您正使用唯一标识设置应用程序池,那么根据服务器上的应用程序和内存资源,将会达到大约 60 个应用程序池的上限 。某些分配了单个新登录会话的系统资源存在一定的限制 。这表明可以有 60 个进程以不同的帐户同时运行 。IIS 6.0 支持在单个共享的工作站和桌面中运行这些进程,所需的成本为在所有各方之间共享单个用户会话的单个封装 。要扩展到 60 个应用程序池以上并共享单个桌面,可将 UseSharedWPDesktop 更改为 DWORD 值 1 。更改此注册表项之后 , 应当可以扩展到上百个应用程序池已及上百个同时运行的工作进程 。
以上为转载,是否恢复正常还需验证!
续:经过上面两个方法后,系统日志还是出错,都是说应用池程序相关的进程(与world wide web通信)致命错误,突然在网上看到一句话,说要给system32的user权限(猜想可能要给system32\temp的权限,因为是discuz的NT版),给了之后,网站可以了,不过错误还是会出现,最终按上述的第一个办法去解决,发现里面的netman的network service权限不见,添加之后,经过几小时的观察,错误没有出来了
【go语言进程退出代码 go语言进程退出代码是什么】go语言进程退出代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言进程退出代码是什么、go语言进程退出代码的信息别忘了在本站进行查找喔 。
推荐阅读
- 包含mysql基于binlog同步redis的词条
- 命令行传文件到linux,向linux传输文件
- 什么是oracle的存储过程,oracle存储过程有什么用
- 平均值函数python 平均值函数公式怎么用
- 小程序开发商授权,微信小程序开发商
- 像素类体育游戏有哪些,像素游戏休闲
- 想在西瓜视频上直播卖货,西瓜视频直播带货怎么弄
- vb.net串口发送乱码 vb串口通信源码
- python温度转换计算机作业,python如何编写温度转换