Linux高性能服务器编程——ch7笔记

第7章 Linux服务器程序规范

7.1 日志

Linux提供rsyslogd守护进程接收用户进程输出的日志和内核日志。

应用程序使用syslog函数与rsyslogd守护进程通信。

void syslog(int priority, const char* message, ...);

openlog函数:改变syslog的默认输出方式。

setlogmask函数:设置syslog的日志掩码(日志过滤,使日志级别大于日志掩码的日志信息被系统忽略)。

closelog函数:关闭日志功能。

7.2 用户信息

真实用户ID(UID)、有效用户ID(EUID)、真实组ID(GID)、有效组ID(EGID)。

一个进程拥有两个用户ID:UID和EUID。EUID存在的目的是方便资源访问:它使得运行程序的用户拥有该程序的有效用户的权限。

有效用户为root的进程称为特权进程。EGID的含义与EUID类似:给运行目标程序的组用户提供有效组的权限。

cpp 复制代码
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    uid_t uid = getuid();
    uid_t euid = geteuid();

    printf("userid is %d, effective userid is:%d \n", uid, euid);

    return 0;
}

进程的UID是启动程序的用户的ID,而EUID则是root账户(文件所有者)的ID。

cpp 复制代码
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 ) ) )
    {
        return false;
    }
	//如果不是root,则已经是目标用户
    if ( uid != 0 )
    {
        return true;
    }
	//切换到目标用户
    if ( ( setgid( gp_id ) < 0 ) || ( setuid( user_id ) < 0 ) )
    {
        return false;
    }

    return true;
}

7.3 进程间关系

每个进程都隶属于一个进程组,因此它们除了PID信息外,还有进程组ID(PGID)。

每个进程组都有一个首领进程,其PGID和PID相同。进程组将一直存在,直到其中所有进程都退出,或者加入到其他进程组。

一个进程只能设置自己或者其子进程的PGID,并且,当子进程调用exec系列函数后,也不能再在父进程中对它设置PGID。

一些有关联的进程组将形成一个会话(session),通过setsid函数实现。调用进程成为会话的首领,新建一个进程组,其PGID就是调用进程的PID,调用进程成为该组的首领。调用进程将甩开终端。

7.4 系统资源限制

物理设备限制(CPU 数量、内存数量等)、系统策略限制(CPU 时间等),以及具体实现的限制(比如文件名的最大长度)。

getrlimit、setrlimit函数:读取和设置系统资源限制。

7.5 改变工作目录和根目录

getcwd函数:获取进程当前工作目录。

chdir函数:改变进程工作目录。

chroot函数:改变进程根目录。并不改变进程的当前工作目录,仍需要用chdir函数将工作目录切换至新的根目录。

7.6 服务器程序后台化

cpp 复制代码
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)系统调用)时,文件的权限将是 mode & 0777
    umask(0);
	//创建新的会话,设置本进程为进程组的首领
    pid_t sid = setsid();
    if (sid < 0)
        return false;
	//切换工作目录
    if ((chdir("/")) < 0)
        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;
}

int daemon(int nochdir, int noclose);

nochdir是否改变工作目录,noclose是否将标准输入、标准输出和标准错误输出都定向到 /dev/null 文件。

相关推荐
承渊政道14 小时前
CentOS 7单机部署Elasticsearch 7.17.29:从启动报错、CRUD验证到固定公网地址的完整过程
linux·elasticsearch·centos·内网穿透·cpolar·单机部署
豆豆14 小时前
2026 年证书寿命 398→200 天:一张到期项台账的字段设计与自动化边界
运维·服务器·cms·网站建设·网站制作·域名·ssl证书
自不量力的A同学14 小时前
MooTool Next 1.3.0 发布
笔记
悟道书生14 小时前
第三方服务器访问视图
运维·服务器
zxanz114 小时前
SSL 证书申请中,服务器验证跟 DNS 解析验证有什么区别?
服务器·网络协议·ssl
进击的荆棘14 小时前
Linux系统——库的原理与制作之ELF文件的形成与加载的过程(上)
linux·elf·动静态库
额额额对了14 小时前
Linux 内核定时器与 DHT11
linux·运维·服务器
别动我齐刘海1 天前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
志尊宝1 天前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
玖石书1 天前
Ubuntu 24.04 UFW 全命令攻略:从入门到端口开放实战
linux·运维·ubuntu