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

- #include <syslog.h>
- void syslog ( int priority, const char* message, ... ); // 可变参数
- #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 /* 调试 */
- #include <syslog.h>
- void openlog ( const char* ident, int logopt, int facility );
- #define LOG_PID 0x01 /* 在日志消息中包含程序PID */
- #define LOG_CONS 0x02 /* 如果消息不能记录到日志文件,则打印至终端 */
- #define LOG_ODELAY 0x04 /* 延迟打开日志功能直到第一次调用syslog */
- #define LOG_NDELAY 0x08 /* 不延迟打开日志功能 */
- #include <syslog.h>
- int setlogmask( int maskpri );
- setlogmask(LOG_ERR); //仅仅记录ERR级别的日志消息
- setlogmask(LOG_UPTO(LOG_ERR)); //记录ERR以及之前的所有日志的消息[0,3]
- #include <syslog.h>
- void closelog();
用户信息
- UID:实际用户ID
- EUID:有效用户ID
- GID:实际组ID
- EGID:有效组ID
- #include <sys/types.h>
- #include <unistd.h>
- uid_t getuid(); //获取实际用户ID
- uid_t geteuid(); //获取有效用户ID
- gid_t getgid(); // 获取实际组ID
- gid_t getegid(); // 获取有效组ID
- int setuid( uid_t uid ); //设置实际用户ID
- int seteuid( uid_t uid ); //设置有效用户ID
- int setgid( gid_t gid ); // 设置实际组ID
- int setegid( gid_t gid ); // 设置有效组ID
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- int main()
- {
- uid_t uid = getuid();
- uid_t euid = geteuid();
- printf("userid is %d,effective userid is %d\n",uid,euid);
- return 0;
- }
- @ubuntu:~$ sudo chown root:root test_uid // 修改目标文件的所有者为root
- @ubuntu:~$ sudo chmod +s test_uid // 设置目标文件的set-user-id 标志 注意这段很重要
- @ubuntu:~$ ./test_uid // 运行程序
- userid is 1000,effective userid is 0
从测试程序的输出来看,进程的UID是启动程序的用户的ID,而EUID则是root账户(文件的所有者) 的ID。
- #include <unistd.h>
- pid_t getpgid( pid_t pid );
- #include <unistd.h>
- int setpgid( pid_t pid, pid_t pgid );
- #include <unistd.h>
- pid_t setsid( void );
- 调用进程成为会话的首领,此时该进程是该会话的唯一成员。
- 新建一个进程组,其PGID就是调用进程的PID,调用进程成为该组的首领。
- 调用进程将甩开终端(如果有的话)。
- #include <unistd.h>
- pid_t getsid ( pid_t pid );


- #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; //硬限制
- };

- #include <unistd.h>
- char* getcwd( char* buf, size_t size );
- int chdir( const char* path );
- #include <unistd.h>
- int chroot( const char* path );
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <fcntl.h>
- bool daemonize()
- {
- pid_t pid = fork();
- if (pid < 0) {
- return false;
- }
- else if (pid > 0) {
- exit(0);
- }
- umask(0);
- //设置新的会话,设置本进程为进程组的首领
- pid_t sid = setsid();
- if (sid < 0)
- return false;
- //切换工作目录
- if ((chdir("/")) < 0)
- return false;
- printf("2. pid: %ld, parent id: %ld\n", (long)getpid(), (long)getppid());
- //关闭标准输入,标准输出,标准错误输出
- 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 main(int argc, char **argv)
- {
- printf("1. pid: %ld, parent id: %ld\n", (long)getpid(), (long)getppid());;
- daemonize();
- return 0;
- }
daemon函数,实现了上述守护进程的功能:
- #include <unistd.h>
- int daemon(int nochdir, int noclose);
nochdir参数用于指定是否改变工作目录,如果是0,则工作目录将设置为”/“, 否则继续使用当前工作目录。
noclose参数为0时,标准输入,标准输出,标准错误输出都被重定向到/dev/null,否则依然使用原来的设备。
调用成功时返回0,失败时返回-1,并设置errno。
Linux 高性能服务器编程——Linux服务器程序规范的更多相关文章
- Linux高性能server编程——Linux网络基础API及应用
Linux网络编程基础API 具体介绍了socket地址意义极其API,在介绍数据读写API部分引入一个有关带外数据发送和接收的程序,最后还介绍了其它一些辅助API. socket地址API 主 ...
- Linux 高性能服务器编程——Linux网络编程基础API
问题聚焦: 这节介绍的不仅是网络编程的几个API 更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系. 这节主要介绍三个方面的内容:套接字(so ...
- Linux高性能server编程——定时器
版权声明:本文为博主原创文章.未经博主允许不得转载. https://blog.csdn.net/walkerkalr/article/details/36869913 定时器 服务器程序通常管 ...
- Linux高性能server编程——I/O复用
IO复用 I/O复用使得程序能同一时候监听多个文件描写叙述符.通常网络程序在下列情况下须要使用I/O复用技术: client程序要同一时候处理多个socket client程序要同一时候处理用户 ...
- Linux高性能server编程——信号及应用
信号 信号是由用户.系统或者进程发送给目标进程的信息.以通知目标进程某个状态的改变或系统异常. Linux信号可由例如以下条件产生: 对于前台进程.用户能够通过输入特殊的终端字符来给它发送信号. ...
- Linux高性能server编程——多线程编程(下)
多线程编程 条件变量 假设说相互排斥锁是用于同步线程对共享数据的訪问的话.那么条件变量则是用于线程之间同步共享数据的值. 条件变量提供了一种线程间的通信机制:当某个共享数据达到某个值得时候,唤醒等待这 ...
- arp学习笔记(linux高性能服务编程)
先看看arp的定义吧 现在linux运行这条命令 tcpdump -i eth0:1 -ent '(dst 192.168.5.190 and src 192.168.5.109)or( dst 19 ...
- Linux高性能server编程——高级I/O函数
高级I/O函数 pipe函数 pipe函数用于创建一个管道,实现进程间的通信. #include <unistd.h> int pipe(int pipefd[2]); 通过pipe ...
- Linux 高性能server编程——高级I/O函数
重定向dup和dup2函数 #include <unistd.h> int dup(int file_descriptor); int dup2(int file_descriptor_o ...
随机推荐
- Java四种线程池的学习与总结
在Java开发中,有时遇到多线程的开发时,直接使用Thread操作,对程序的性能和维护上都是一个问题,使用Java提供的线程池来操作可以很好的解决问题. 一.new Thread的弊端 执行一个异步任 ...
- Markdown 编辑器使用指南
Markdown 编辑器使用指南 1.快捷键 加粗: Ctrl/Cmd + B 标题: Ctrl/Cmd + H 插入链接: Ctrl/Cmd + K 插入代码: Ctrl/Cmd + Shift + ...
- Java IO(四)
在文件操作流中,输入输出的目标都是文件,但是有时候,我们并不需要写入文件,只是需要中转一下而已,这样就会显得很麻烦,所以我们就可以使用内存操作流.在内存操作流中,输入输出目标都是内存. 内存输出流:B ...
- [JSOI 2011]分特产
Description JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望 ...
- [WC 2011]Xor
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...
- hdu 5887 搜索+剪枝
Herbs Gathering Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- NOIP2014-5-10模拟赛
Problem 1 机器人(robot.cpp/c/pas) [题目描述] 早苗入手了最新的Gundam模型.最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧. 早苗的新模型可以按照输入的 ...
- ●BZOJ 2839 集合计数
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2839 题解: 容斥原理 真的是神题!!! 定义 f[k] 表示交集大小至少为 k时的方案数怎 ...
- solr6.6初探之分词篇
关于solr6.6搭建与配置可以参考 solr6.6初探之配置篇 在这里我们探讨一下分词的配置 一.关于分词 1.分词是指将一个中文词语拆成若干个词,提供搜索引擎进行查找,比如说:北京大学 是一个词那 ...
- mysql免安装版下载及配置教程
第一步:下载 下载地址:http://dev.mysql.com/downloads/mysql/ 滚动到下方就能看到了,根据自己的需求下载: 我的电脑为64为的所以下载的为 Windows (x86 ...