文章目录

  • ​​一、服务器程序规范的基本内容​​
  • ​​(2)守护进程、记录后台进程日志位置:/var/log、服务器程序的配置文件位置:/etc、后台进程PID的位置:/var/run​​
  • ​​二、日志​​
  • ​​1.Linux系统日志​​
  • ​​(1)守护进程:syslogd​​
  • ​​(2)升级版守护进程:rsyslogd​​
  • ​​2.syslog函数​​
  • ​​(1)应用程序使用syslog函数与rsyslogd守护进程通信​​
  • ​​(2)openlog函数可以改变syslog的默认输出方式​​
  • ​​(3)设置syslog日志掩码​​
  • ​​三、用户信息​​
  • ​​1.UID和EUID、GID和EGID的简单知识​​
  • ​​2.进程的UID和EUID的区别​​
  • ​​3.将root身份启动的进程切换为普通用户身份运行​​
  • ​​四、进程间的关系​​
  • ​​1.进程的PID和PGID​​
  • ​​2.会话​​
  • ​​3.ps查看进程关系:ps -o pid,ppid,pgid,sid,comm | less​​
  • ​​4.系统资源限制​​
  • ​​(1)getrlimit函数,setrlimit函数,rrlimit结构体​​
  • ​​(2)ulimit命令和配置文件​​
  • ​​5.改变工作目录和根目录​​
  • ​​(1)getcwd函数和chdir函数​​
  • ​​(2)chroot函数​​
  • ​​6.服务器程序的后台化、​​

一、服务器程序规范的基本内容

(1)服务器程序通常要考虑很多细节问题,这些细节问题面广且零碎,而且基本都是模板式的

(2)守护进程、记录后台进程日志位置:/var/log、服务器程序的配置文件位置:/etc、后台进程PID的位置:/var/run

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件

二、日志

1.Linux系统日志

(1)守护进程:syslogd

linux系统上提供了一个守护进程来处理系统日志——syslogd,但是现在的Linux上使用的都是它的升级版——rsyslogd

(2)升级版守护进程:rsyslogd

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件_02

  • rsyslogd守护进程既能接收用户进程输出的日志,又能接收内核日志
    对于用户空间输出的日志而言,

    对于内核空间输出的日志而言
  • rsyslogd守护进程与其配置文件

2.syslog函数

(1)应用程序使用syslog函数与rsyslogd守护进程通信

  • syslog函数的定义如下:
  • (第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_03


  • 日志级别有如下几个:
  • (第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件_04


(2)openlog函数可以改变syslog的默认输出方式

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_05


(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_06

(3)设置syslog日志掩码

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_07

三、用户信息

1.UID和EUID、GID和EGID的简单知识

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_08

2.进程的UID和EUID的区别

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_09


(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_10


eg:

#include <unistd.h>
#include <stdio.h>

int main()
{
uid_t uid = getuid();
uid_t euid = geteuid();
printf( "userid is %d, effective userid is: %d\n", uid, euid );
return 0;
}
  • 直接运行得到的结果是:
    userid is 0, effective userid is: 0
  • 如果按照下面的方式运行的话
  • (第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件_11


3.将root身份启动的进程切换为普通用户身份运行

static bool switch_to_user( uid_t user_id, gid_t gp_id )
{
//先确保目标用户和组不是root
if ( ( user_id == 0 ) && ( gp_id == 0 ) )
{
return false;
}
//确保当前用户是合法用户:root或者目标用户
gid_t gid = getgid();
uid_t uid = getuid();
if ( ( ( gid != 0 ) || ( uid != 0 ) ) && ( ( gid != gp_id ) || ( uid != user_id ) ) ) //if ( ( ( gid == 0 ) || ( uid == 0 ) ) && ( ( gid != gp_id ) && ( uid != user_id ) ) )更好一些
{
return false;
}
//如果不是root,则已经是目标用户
if ( uid != 0 )
{
return true;
}
//切换到目标用户
if ( ( setgid( gp_id ) < 0 ) || ( setuid( user_id ) < 0 ) )//这段代码倒着写,更好理解
{
return false;
}

return true;
}
四、进程间的关系

1.进程的PID和PGID

(1)getpgid函数

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_12


(2)setpgid函数

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_13

2.会话

(1)setsid函数

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_14


(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_15


(2)getsid函数

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_16

3.ps查看进程关系:ps -o pid,ppid,pgid,sid,comm | less

  • 执行ps命令可以查看进程、进程组和会话之间的关系:
  • (第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件_17


4.系统资源限制

(1)getrlimit函数,setrlimit函数,rrlimit结构体

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_18


(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_19


(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_20

(2)ulimit命令和配置文件

  • ulimit命令可以修改当前shell环境下的资源限制(软限制或/和硬限制),这种限制将对该shell启动的所有后续程序有效
  • 修改配置文件也可以改变系统软限制和硬限制,而且这种修改是永久的

5.改变工作目录和根目录

(1)getcwd函数和chdir函数

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_后台进程_21


(第7章)《Linux高性能服务器编程》Linux服务器程序规范_守护进程_22

(2)chroot函数

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件_23

6.服务器程序的后台化、

(1)方法1
eg:如何在代码中让一个进程以守护进程的方式运行,守护进程的编写需要遵循一定的步骤

bool daemonize()
{
//创建子进程,关闭父进程,这样可以使得进程在后台运行
pid_t pid = fork();
if ( pid < 0 )
{
return false;
}
else if ( pid > 0 )
{
exit( 0 );
}
//设置文件权限掩码,当进程创建新文件(使用open(const char *pathname, int flags, mode_t mode)系统调用)时,文件的权限将是 & 0777。这个077是默认创建的
umask( 0 );
//创建新的会话,设置本进程为进程组的首领
pid_t sid = setsid();
if ( sid < 0 )
{
return false;
}
//切换工作目录
if ( ( chdir( "/" ) ) < 0 )
{
/* Log the failure */
return false;
}
//关闭标准输入设备、标准输出设备和标准错误输出设备
close( STDIN_FILENO );
close( STDOUT_FILENO );
close( STDERR_FILENO );
//关闭已打开的文件描述符,代码省
//将标准输入、标准输出和标准错误输出都重定向到/dev/null文件
open( "/dev/null", O_RDONLY );
open( "/dev/null", O_RDWR );
open( "/dev/null", O_RDWR );
return true;
}

(2)方法2

(第7章)《Linux高性能服务器编程》Linux服务器程序规范_配置文件_24