问题聚焦:
    除了网络通信外,服务器程序通常还必须考虑许多其他细节问题,这些细节问题涉及面逛且零碎,而且基本上是模板式的,所以称之为服务器程序规范。
    工欲善其事,必先利其器,这篇主要来探讨服务器程序的一些主要规范。

概览:
  • Linux服务器程序一般以后台程序的形式运行,后台进程又称为守护进程。
  • Linux服务器程序一般以某个专门的非root身份运行。
  • Linux服务器程序通常是可配置的,命令行或者配置文件的形式。
  • Linux服务器程序通常会在启动的时候生成一个PID文件,以记录该后台进程的PID。
  • Linux服务器程序通常需要考虑系统资源和限制。

日志
守护进程:rsyslogd
功能:接收用户进程输出的日志,又能接收内核日志。
用户日志函数:syslog
功能:生成系统日志,输出到一个UNIX本地域socket类型(AF_UNIX)的文件/dev/log中。rsyslogd则监听该文件以获取用户进程的输出。
内核日志函数:printk
功能:打印至内核的环状缓存中,环状缓存的内容直接映射到/proc/kmsg文件中。rsyslogd则通过读取该文件获得内核日志。
处理流程如下图所示:
syslog函数
功能:应用程序使用syslog函数与rsyslogd守护进程通信。
函数定义:
#include <syslog.h>
void syslog ( int priority, const char* message, ... ); // 可变参数
函数说明:
第二个和第三个参数为可变参数,为了结构化输出
priority参数:设施值与日志级别的按位或。
    设施值的默认值是LOG_USER,可选值如下:
#include <syslog.h>
#define LOG_EMERG 0 /* 系统不可用 */
#define LOG_ALERT 1 /* 报警,需要立即采取动作 */
#define LOG_CRIT 2 /* 非常严重的情况 */
#define LOG_ERR 3 /* 错误 */
#define LOG_WARNING 4 /* 警告 */
#define LOG_NOTICE 5 /* 通知 */
#define LOG_INFO 7 /* 信息 */
#define LOG_DEBUG 8 /* 调试 */
函数:openlog
声明:
#include <syslog.h>
void openlog ( const char* ident, int logopt, int facility );
作用:改变syslog的默认输出方式,进一步结构化日志内容
函数说明:
ident:指定的字符串将被添加到日志消息的日期和时间之后,通常被设置为程序的名字。
logopt:对后续syslog调用的行为进行配置,可去下列值的按位或
#define    LOG_PID        0x01            /* 在日志消息中包含程序PID */
#define LOG_CONS 0x02 /* 如果消息不能记录到日志文件,则打印至终端 */
#define LOG_ODELAY 0x04 /* 延迟打开日志功能直到第一次调用syslog */
#define LOG_NDELAY 0x08 /* 不延迟打开日志功能 */
facility:修改syslog函数中的默认设施值
日志掩码:使日志级别大于日志掩码的日至信息被系统忽略。
函数:
#include <syslog.h>
int setlogmask( int maskpri );
函数说明:
maskpri:指定日志掩码值
该函数始终会成功,返回调用进程先前的日志掩码值。
关闭日志功能:
#include <syslog.h>
void closelog();

用户信息
用户信息包括:
  • UID:真是用户ID
  • EUID:有效用户ID
  • GID:真实组
  • EGID:有效组
#include <sys/types.h>
#include <unistd.h>
uid_t getuid();
uid_t geteuid();
gid_t getgid();
gid_t getegid();
int setuid( uid_t uid );
int seteuid( uid_t uid );
int setgid( gid_t gid );
int setegid( gid_t gid );
从函数名很容易看出函数的作用,就不解释了。
说明一下UID和EUID的区别:
一个进程拥有两个用户ID:UID和EUID。
EUID存在的目的是暂时提升当前用户的权限,方便资源访问,使得运行程序的用户拥有该资源的有效用户的权限,比如root用户。

进程间关系
进程组
进程中:每个进程都隶属于一个进程组,所以每个进程还有一个继承祖ID,PGID。
函数:
#include <unistd.h>
pid_t getpgid( pid_t pid );
每个进程都有一个首领进程,其PGID和PID相同。进程组将一直存在,直到其中所有进程都退出,或者加入到其他进程中。
设置PGID函数:
#include <unistd.h>
int setpgid( pid_t pid, pid_t pgid );
作用:将PID为pid的进程的PGID设置为pgid。
一个进程只能设置子集或者其子进程的PGID,并且,当子进程调用exec系列函数后,我们也不能再在父进程中对它设置。
会话
会话:一些有关联的进程组形成一个会话。
函数:
#include <unistd.h>
pid_t setsid( void );
函数说明:
  1. 该函数不能由进程组的首领进程调用,否则将产生一个错误。只能由非组首领的进程调用。
  2. 调用后创建新会话
  3. 调用几次呢很难过成为会话的首领,此时该进程是该会话的唯一成员
  4. 调用一个进程组,其PGID就是调用进程的PID,调用进程成为该组的首领。
  5. 调用进程将甩开终端
  6. 调用成功返回新的进程组的PGID,失败则返回-1并设置errno
会话ID即为首领所在进程组的PGID,获取函数
#include <unistd.h>
pid_t getsid ( pid_t pid );
用ps命令查看进程关系
调用结果如图(PPID为父进程的PID):
 
三个进程的关系如图:
 

系统资源限制
Linux系统资源限制可以通过如下一对函数来读取和设置:
#include <sys/resource.h>
int getrlimit( int resource, struct rlimit *rlim );
int setrlimit( int resource, const struct rlimit *rlim );
rlimit结构体的定义如下:
struct rlimit
{
rlim_t rlim_cur;
rlim_t rlim_max;
};
函数说明:
rlim_t是一个整数类型,它描述资源级别。
rlim_cur成员指定资源的软限制,建议性。
rlim_max成员指定资源的硬限制。
resource:指定资源限制类型。
部分资源限制类型如下所示:
 
 

改变工作目录和根目录
获取当前工作目录和改变进程工作目录的函数分别是:
#include <unistd.h>
char* getcwd( char* buf, size_t size );
int chdir( const char* path );
函数说明:
buf:指向的内存用于存储进程当前工作目录的绝对路径
size:指定buf的大小,如果当前工作目录的绝对路径的长度超过了size,则getcwd将返回NULL,并设置errno为ERANGE。
path:指定要切换的目标目录。成功时返回0,失败返回-1并设置errno。
改变进程根目录的函数是chroot,其定义如下:
#include <unistd.h>
int chroot( const char* path );
函数说明:
path:指定要切换的目标根目录。
chroot并不改变进程的当前工作目录,所以调用chroot之后,我们仍需要使用chdir("/")来将工作目录切换至新的根目录。

服务器程序后台化
Key word:守护进程
后面将以专题的形式总结。
小结:
这章虽然叫做程序规范,其实更多的是介绍一些开发过程,特别是中大型项目中很有用的技巧,可以提高我们的开发和调试效率。
后面将会介绍一些常用的设计框架,这些都是比较基础的知识。后面如果还有时间,希望可以用我们学到的这些知识做一个小项目出来。也算是学以致用了。
参考资料:
《Linux高性能服务器编程》

服务器编程入门(5)Linux服务器程序规范的更多相关文章

  1. 服务器编程入门(4)Linux网络编程基础API

      问题聚焦:     这节介绍的不仅是网络编程的几个API     更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系.     这节主要介绍三个方面的内容:套接字( ...

  2. 服务器编程入门(10)TCP回射服务器实现 - 并发

    问题聚焦:     在前面我们大概浏览了一下服务器编程需要掌握的一些知识和技术,以及架构思想.        实践,才是检验真理的唯一标准..从这节起我们将在这些技术的基础上,一步步实现以及完善一个服 ...

  3. 服务器编程入门(7)I/O复用

    问题聚焦:     前篇提到了I/O处理单元的四种I/O模型.     本篇详细介绍实现这些I/O模型所用到的相关技术.     核心思想:I/O复用 使用情景: 客户端程序要同时处理多个socket ...

  4. 服务器编程入门(3)TCP协议详解

    问题聚焦:     本节从如下四个方面讨论TCP协议:     TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流     TCP状态转移过程:TCP连接的任意一 ...

  5. 服务器编程入门(2)IP协议详解

    问题聚焦:     IP协议是TCP/IP协议族的核心协议,也是socket网络编程的基础之一.这里从两个方面较为深入地探讨IP协议:     1,IP头部信息(指定IP通信的源端IP地址,目的端IP ...

  6. 服务器编程入门(1)TCP/IP协议族

    问题聚焦: 简单地梳理一下TCP/IP各层的功能和常用协议 详细了解ARP(数据链路层)和DNS(应用层)协议的工作原理 1 TCP/IP协议族体系结构 数据链路层:     职责:实现网卡接口的网络 ...

  7. 服务器编程入门(11)TCP并发回射服务器实现 - 单线程select实现

    问题聚焦: 当客户端阻塞于从标准输入接收数据时,将读取不到别的途径发过来的必要信息,如TCP发过来的FIN标志. 因此,进程需要内核一旦发现进程指定的一个或多个IO条件就绪(即输入已准备好被读取,或者 ...

  8. 从Windows 服务器通过sync向Linux服务器定时同步文件

    本文解决的是Windows 下目录及文件向Linux同步的问题,Windows向 Windows同步的请参考:http://www.idcfree.com/article-852-1.html 环境介 ...

  9. 服务器编程入门(13) Linux套接字设置超时的三种方法

    摘要:     本文介绍在套接字的I/O操作上设置超时的三种方法. 图片可能有点宽,看不到的童鞋可以点击图片查看完整图片.. 1 调用alarm 使用SIGALRM为connect设置超时 设置方法: ...

随机推荐

  1. 更快地从IplImage转换成QImage

    转:http://blog.sina.com.cn/s/blog_5c70dfc80100qzif.html 在Qt平台上使用OpenCV肯定会遇到从IplImage到QImage的转换问题,找了很多 ...

  2. SpringMVC记住密码功能

    CookieTool (Cookie帮助类): package com.utcsoft.common.cookie; import java.util.HashMap; import java.uti ...

  3. GitHub详解(转)

    GitHub 是一个共享虚拟主机服务,用于存放使用Git版本控制的软件代码和内容项目.它由GitHub公司(曾称Logical Awesome)的开发者Chris Wanstrath.PJ Hyett ...

  4. 基于visual Studio2013解决C语言竞赛题之1067间隔排序

        题目 解决代码及点评 /* 功能:间隔元素排序.用随机函数产生25个[25,75]之间的整数, 把它送到一维数组M中. 要求对M[I],M[I+J],M[I+2*J],-这些元 ...

  5. 正则表达式概述与JAVA中正则表达式的应用

    编程或者电脑使用过程中,经常需要对字符串进行 匹配,查找,替换,判断.如果单纯用代码 if () ,whlie 什么的进行比较复杂麻烦.正则表达式是一种强大灵活的文本处理工具,专门对字符串进行匹配,查 ...

  6. 由href return false 来看阻止默认事件

    很多时候我们都想阻止一个a ?link的href跳转. 1 <a onclick=” return false ;” href=”www. 360 .cn”>click</a> ...

  7. 在命令行获取标准输入序列的反互序列,pep序列和长度信息

    近期对序列文件处理的比較多,时常要看一些核酸序列的反向互补序列,长度.可能的翻译序列. 曾经我常用seqBuider 来查看.假设能在命令行直接查看.想必是极好的. 这是一个perl脚本.只是我把它的 ...

  8. ASP.NET - TreeView 增删

    效果: 前端代码: <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Si ...

  9. boa-0.94.13:Hello CGI

    CGI是什么 CGI全称是CommonGateway Interface,简称CGI,中文名叫做通用网关接口. CGI程序就是符合CGI接口规范的程序,相对于WebServer来说也叫外部程序. CG ...

  10. ADS1.2安装

    一.ADS1.2的安装 1. 解压 2. 双击打开ads1.2 3.我们选择当中的SETUP.EXE文件,进行安装 4.点击Next: 5.这是许可文件,假设允许的话选择Yes: 6.选择安装文件夹, ...