xunwap

专注移动互联网服务

正在浏览 Linux 里的文章

简单地说,可以把服务器以三个方面来进行概括: 功能,性能,稳定性。那么这三者之中谁最重要呢?严格来讲,脱离具体的环境来讨论这个问题似乎并不合适,但是如果一定要给这三者进行排序,我认为”稳定性”是最重要的。
从产品的角度上来说,一个产品的功能可以简单,性能也可以相对较低,但是如果这个产品足够稳定,那么就可以给用户带来持续良好的用户体验;另一方面,如果一个产品的功能强大,性能也不错,但是不够稳定,那么很容易让用户反感而使用户流失。
特定于Linux环境下,如何开发出足够稳定的server呢?这个问题很宽泛,可以考虑的点也很多,下面我从其中的一点进行讨论。
在Linux环境下进行开发,对于”信号(signal)”这个概念大家一定比较熟悉,除了有意在特定的场景中使用信号来完成一些任务之外,很多时候,对信号的处理不当或是理解有误就会产生很多问题。

Linux中用户进程中可以接收信号如下:

名称 默认动作 说明

SIGHUP 终止进程 终端线路挂断

SIGINT 终止进程 中断进程

SIGQUIT 建立CORE文件终止进程,并且生成core文件

SIGILL 建立CORE文件 非法指令

SIGTRAP 建立CORE文件 跟踪自陷

SIGBUS 建立CORE文件 总线错误

SIGSEGV 建立CORE文件 段非法错误

SIGFPE 建立CORE文件 浮点异常

SIGIOT 建立CORE文件 执行I/O自陷

SIGKILL 终止进程 杀死进程

SIGPIPE 终止进程 向一个没有读进程的管道写数据

SIGALARM 终止进程 计时器到时

SIGTERM 终止进程 软件终止信号

SIGSTOP 停止进程 非终端来的停止信号

SIGTSTP 停止进程 终端来的停止信号

SIGCONT 忽略信号 继续执行一个停止的进程

SIGURG 忽略信号 I/O紧急信号

SIGIO 忽略信号 描述符上可以进行I/O

SIGCHLD 忽略信号 当子进程停止或退出时通知父进程

SIGTTOU 停止进程 后台进程写终端

SIGTTIN 停止进程 后台进程读终端

SIGXGPU 终止进程 CPU时限超时

SIGXFSZ 终止进程 文件长度过长

SIGWINCH 忽略信号 窗口大小发生变化

SIGPROF 终止进程 统计分布图用计时器到时

SIGUSR1 终止进程 用户定义信号1

SIGUSR2 终止进程 用户定义信号2

SIGVTALRM 终止进程 虚拟计时器到时

更详细的说明:

1) SIGHUP 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联.
2) SIGINT 程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出
3) SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl-\)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号.
4) SIGILL 执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行数据段. 堆栈溢出时也有可能产生这个信号.
5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用.
6) SIGABRT 程序自己发现错误并调用abort时产生.
7) SIGIOT 在PDP-11上由iot指令产生, 在其它机器上和SIGABRT一样.
8)SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数, 但其地址不是4的倍数.
9) SIGFPE 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误.
10) SIGKILL 用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略.
11) SIGUSR1 留给用户使用
12) SIGSEGV 试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.
13) SIGUSR2 留给用户使用
14) SIGPIPE Broken pipe
15) SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号.
16) SIGTERM 程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这个信号.
17) SIGCHLD 子进程结束时, 父进程会收到这个信号.
18) SIGCONT 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用一个handler来让程序在由stopped状态变为继续执行时完成特定的工作. 例如, 重新显示提示符
19) SIGSTOP 停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别: 该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.
20) SIGTSTP 停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时(通常是Ctrl-Z)发出这个信号
21) SIGTTIN 当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN信号. 缺省时这些进程会停止执行.
22) SIGTTOU 类似于SIGTTIN, 但在写终端(或修改终端模式)时收到.
23) SIGURG 有紧急数据或out-of-band数据到达socket时产生.
24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变
25) SIGXFSZ 超过文件大小资源限制.
26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.
27) SIGPROF 类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的时间.
28) SIGWINCH 窗口大小改变时发出.
29) SIGIO 文件描述符准备就绪, 可以开始进行输入/输出操作.
30) SIGPWR Power failure

如果我们没有在server中对这些可能出现在server运行过程中的信号进行处理,那么依据上面的信息来看,对于进程中未处理的信号,系统有三种处理方式: 忽略信号,停止进程,进程退出。
“忽略信号”这种操作对于server的稳定性并没有影响,但是”停止进程”和”进程退出”就对server的稳定性有很大影响,也就是说,系统的缺省信号处理方式会使得进程在运行的过程中异常退出,对于一个稳定的server而言,这显然是不应该出现的。换句话说,在设计一个server时,我们必须在server中对可能出现的信号,尤其是那些可能使得server退出的信号进行手工处理而不是使用系统的缺省信号处理方式。

在进行网络开发时,一些新手经常会遇到”Broken pipe,process exit…”之类的进程退出信息,出现这个问题的原因是”当数据接收端关闭一个连接时,若数据发送端依然持续往这个连接上发送数据,那么数据发送端会收到一个RST响应,数据发送端如果忽略连接断开的事实而继续通过这个断开的连接发送数据,那么系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已断开不能再发送数据,如果进程没有自定义这个SIGPIPE信号处理函数,那么系统会使用缺省的信号处理函数来处理这个信号,也即是调用 terminate 函数来终止进程”。但是如果我们自定义了SIGPIPE信号的处理函数,那么系统就会调用我们的信号处理函数而不会调用terminate使得进程退出。

上面只是一个常见的例子,进一步说明,在设计一个稳定的server时,必须自定义系统中可能影响进程稳定的信号处理方式。
在一些优秀的server代码中,我们经常可以看到在main函数的入口处会出现”安装信号处理函数的代码”,这也是增强系统稳定性的一种体现。

本站原创文章,转载请注明出处。

每一个人都有自己的代码网格,比如代码缩进;大括号是否单独成行…
当然,没有哪种代码网格是最好的,找到一种适合自己的风格并坚持使用,那就是最好的。
如果需要阅读一种与自己的代码风格完全不同的代码将是一件非常不愉快的事情,这个时候,如果有一种工具能将代码转换成我们自己的代码风格该有多么好。实际上,这样的工具很多,这里介绍一种使用简单,功能强大的代码格式化工具:  AStyle

AStyle是一种开源的跨平台的代码格式化工具,在Linux/Windows均可使用。

使用方法如下:

Artistic Style 1.24
Maintained by: Jim Pattee
Original Author: Tal Davidson

Usage : astyle [options] Source1.cpp Source2.cpp [...]
astyle [options] < Original > Beautified

When indenting a specific file, the resulting indented file RETAINS the
original file-name. The original pre-indented file is renamed, with a
suffix of “.orig” added to the original filename.

Wildcards (* and ?) may be used in the filename.
A ‘recursive’ option can process directories recursively.

By default, astyle is set up to indent C/C++/C#/Java files, with four
spaces per indent, a maximal indentation of 40 spaces inside continuous
statements, a minimum indentation of eight spaces inside conditional
statements, and NO formatting options.

Option’s Format:
—————-
Long options (starting with ‘–’) must be written one at a time.
Short options (starting with ‘-’) may be appended together.
Thus, -bps4 is the same as -b -p -s4.

Predefined Style Options:
————————-
–style=allman OR –style=ansi OR –style=bsd OR -A1
Allman style formatting/indenting.
Broken brackets.

–style=java OR -A2
Java style formatting/indenting.
Attached brackets.

–style=k&r OR –style=k/r OR -A3
Kernighan & Ritchie style formatting/indenting.
Linux brackets.

–style=stroustrup OR -A4
Stroustrup style formatting/indenting.
Stroustrup brackets.

–style=whitesmith OR -A5
Whitesmith style formatting/indenting.
Broken, indented brackets.
Indented class blocks and switch blocks.

–style=banner OR -A6
Banner style formatting/indenting.
Attached, indented brackets.
Indented class blocks and switch blocks.

–style=gnu OR -A7
GNU style formatting/indenting.
Broken brackets, indented blocks, indent is 2 spaces.

–style=linux OR -A8
GNU style formatting/indenting.
Linux brackets, indent is 8 spaces.

–style=horstmann OR -A9
Horstmann style formatting/indenting.
Horstmann brackets, indented switches, indent is 3 spaces.

–style=1tbs OR –style=otbs OR -A10
One True Brace Style formatting/indenting.
Linux brackets, add brackets to all conditionals.

Tab and Bracket Options:
————————
default indent option
If no indentation option is set,
the default option of 4 spaces will be used.

–indent=spaces=# OR -s#
Indent using # spaces per indent. Not specifying #
will result in a default of 4 spaces per indent.

–indent=tab OR –indent=tab=# OR -t OR -t#
Indent using tab characters, assuming that each
tab is # spaces long. Not specifying # will result
in a default assumption of 4 spaces per tab.

–indent=force-tab=# OR -T#
Indent using tab characters, assuming that each
tab is # spaces long. Force tabs to be used in areas
Astyle would prefer to use spaces.

default brackets option
If no brackets option is set,
the brackets will not be changed.

–brackets=break OR -b
Break brackets from pre-block code (i.e. ANSI C/C++ style).

–brackets=attach OR -a
Attach brackets to pre-block code (i.e. Java/K&R style).

–brackets=linux OR -l
Break definition-block brackets and attach command-block
brackets.

–brackets=stroustrup OR -u
Attach all brackets except function definition brackets.

–brackets=horstmann OR -g
Break brackets from pre-block code, but allow following
run-in statements on the same line as an opening bracket.

Indentation options:
——————–
–indent-classes OR -C
Indent ‘class’ blocks, so that the inner ‘public:’,
‘protected:’ and ‘private: headers are indented in
relation to the class block.

–indent-switches OR -S
Indent ‘switch’ blocks, so that the inner ‘case XXX:’
headers are indented in relation to the switch block.

–indent-cases OR -K
Indent case blocks from the ‘case XXX:’ headers.
Case statements not enclosed in blocks are NOT indented.

–indent-brackets OR -B
Add extra indentation to ‘{‘ and ‘}’ block brackets.

–indent-blocks OR -G
Add extra indentation entire blocks (including brackets).

–indent-namespaces OR -N
Indent the contents of namespace blocks.

–indent-labels OR -L
Indent labels so that they appear one indent less than
the current indentation level, rather than being
flushed completely to the left (which is the default).

–indent-preprocessor OR -w
Indent multi-line #define statements.

–indent-col1-comments OR -Y
Indent line comments that start in column one.

–max-instatement-indent=# OR -M#
Indent a maximal # spaces in a continuous statement,
relative to the previous line.

–min-conditional-indent=# OR -m#
Indent a minimal # spaces in a continuous conditional
belonging to a conditional header.

Padding options:
——————–
–break-blocks OR -f
Insert empty lines around unrelated blocks, labels, classes, …

–break-blocks=all OR -F
Like –break-blocks, except also insert empty lines
around closing headers (e.g. ‘else’, ‘catch’, …).

–pad-oper OR -p
Insert space paddings around operators.

–pad-paren OR -P
Insert space padding around parenthesis on both the outside
and the inside.

–pad-paren-out OR -d
Insert space padding around parenthesis on the outside only.

–pad-paren-in OR -D
Insert space padding around parenthesis on the inside only.

–pad-header OR -H
Insert space padding after paren headers (e.g. ‘if’, ‘for’…).

–unpad-paren OR -U
Remove unnecessary space padding around parenthesis. This
can be used in combination with the ‘pad’ options above.

–delete-empty-lines OR -x
Delete empty lines within a function or method.
It will NOT delete lines added by the break-blocks options.

–fill-empty-lines OR -E
Fill empty lines with the white space of their
previous lines.

Formatting options:
——————-
–break-closing-brackets OR -y
Break brackets before closing headers (e.g. ‘else’, ‘catch’, …).
Use with –brackets=attach, –brackets=linux,
or –brackets=stroustrup.

–break-elseifs OR -e
Break ‘else if()’ statements into two different lines.

–add-brackets OR -j
Add brackets to unbracketed one line conditional statements.

–add-one-line-brackets OR -J
Add one line brackets to unbracketed one line conditional
statements.

–keep-one-line-blocks OR -O
Don’t break blocks residing completely on one line.

–keep-one-line-statements OR -o
Don’t break lines containing multiple statements into
multiple single-statement lines.

–convert-tabs OR -c
Convert tabs to the appropriate number of spaces.

–align-pointer=type OR -k1
–align-pointer=middle OR -k2
–align-pointer=name OR -k3
Attach a pointer or reference operator (* or &) to either
the operator type (left), middle, or operator name (right).

–mode=c
Indent a C or C++ source file (this is the default).

–mode=java
Indent a Java source file.

–mode=cs
Indent a C# source file.

Other options:
————–
–suffix=####
Append the suffix #### instead of ‘.orig’ to original filename.

–suffix=none OR -n
Do not retain a backup of the original file.

–options=####
Specify an options file #### to read and use.

–options=none
Disable the default options file.
Only the command-line parameters will be used.

–recursive OR -r OR -R
Process subdirectories recursively.

–exclude=####
Specify a file or directory #### to be excluded from processing.

–errors-to-stdout OR -X
Print errors and help information to standard-output rather than
to standard-error.

–preserve-date OR -Z
The date and time modified will not be changed in the formatted file.

–verbose OR -v
Verbose mode. Extra informational messages will be displayed.

–formatted OR -Q
Formatted display mode. Display only the files that have been formatted.

–quiet OR -q
Quiet mode. Suppress all output except error messages.

–lineend=windows OR -z1
–lineend=linux OR -z2
–lineend=macold OR -z3
Force use of the specified line end style. Valid options
are windows (CRLF), linux (LF), and macold (CR).

–version OR -V
Print version number.

–help OR -h OR -?
Print this help message.

Default options file:
———————
Artistic Style looks for a default options file in the
following order:
1. The contents of the ARTISTIC_STYLE_OPTIONS environment
variable if it exists.
2. The file called .astylerc in the directory pointed to by the
HOME environment variable ( i.e. $HOME/.astylerc ).
3. The file called astylerc in the directory pointed to by the
USERPROFILE environment variable ( i.e. %USERPROFILE%\astylerc ).
If a default options file is found, the options in this file
will be parsed BEFORE the command-line options.
Long options within the default option file may be written without
the preliminary ‘–’.

例如,我们需要以ANSI代码风格来格式化 “E:\Code\Sample\”目标下以及子目录下所有的 CPP 文件,那么使用的命令如下:

AStyle.exe -A1 -r .\*.cpp

运行这个命令之后,原始的cpp文件都会以.orig后缀进行了备份。

如果在格式化的过程中不需要进行备份,那么可以使用”-n”参数,对应的命令如下:

AStyle.exe -A1 -rn .\*.cpp

本站原创文章,转载请注明出处。