守护进程&IO多路复用介绍

一、守护进程

1、逻辑介绍

2、相关系统调用和库函数

监控系统日志文件查看

测试用例

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<syslog.h>
#include<string.h>
#include<fcntl.h>
#include<signal.h>
#include<string.h>
#include<errno.h>

pid_t pid;
int is_shutdown = 0;

void signal_handler(int sig)
{
    switch (sig)
    {
    case SIGHUP:
        syslog(LOG_WARNING,"收到SIGHUP信号...");
        break;
    case SIGTERM:
        syslog(LOG_NOTICE,"接收到终止信号,准备退出守护进程...");
        syslog(LOG_NOTICE,"向子进程发送SIGTERM信号...");
        is_shutdown = 1;
        kill(pid,SIGTERM);
        break;
    default:
        syslog(LOG_INFO,"Received unhandled signal");
        break;
    }
}

void my_damonize()
{
    pid_t pid;
    //先fork创建两个进程
    pid =fork();
    if (pid < 0)
    {
        exit(EXIT_FAILURE);
    }
    //马上关闭掉父进程
    //当前进程会变成孤儿进程 挂到祖先
    if (pid > 0)
    {
        exit(EXIT_SUCCESS);
    }
    //设置新的会话ID ->摆脱和当前窗口的联系
    if(setsid() < 0)
    {
        exit(EXIT_FAILURE);
    }
    //处理SIGHUP、SIGTERM信号
    signal(SIGHUP,signal_handler);
    signal(SIGTERM,signal_handler);
    //再次fork
    pid =fork();
    if (pid < 0)
    {
        exit(EXIT_FAILURE);
    }
    //再次退出父进程 -> 当前不再是会话的领导 永远不会受到窗口的影响
    if (pid > 0)
    {
        exit(EXIT_SUCCESS);
    }
    //重置umask
    umask(0);
    //将工作目录切换为根目录
    chdir("/");
    //关闭所有打开的文件描述符
    for (int x = 0; x <= sysconf(_SC_OPEN_MAX); x++)
    {
        close(x);
    }
    //开启系统日志
    openlog("this is our daemonize process:",LOG_PID,LOG_DAEMON);
}
int main()
{
    //初始化守护进程
    my_damonize();

    while (1)
    {
        pid = fork();
        if (pid > 0)
        {
            syslog(LOG_INFO,"守护进程正在监听服务端进程...");
            waitpid(-1,NULL,0);
            if (is_shutdown)
            {
                syslog(LOG_NOTICE,"子进程已被回收,即将关闭syslog连接,守护进程退出");
                closelog();
                exit(EXIT_SUCCESS);
            }
            syslog(LOG_ERR,"服务端进程终止,3s后重启...");
            sleep(3);
        }
        else if(pid  == 0)
        {
            syslog(LOG_INFO,"子进程fork成功");
            syslog(LOG_INFO,"启动服务端进程");

            char *path = "/home/lxl/daemon_and_multiplex/tcp_server";
            char *argv[]={"my_tcp_server",NULL};
            errno = 0;
            execve(path,argv,NULL);
            char buf[1024];
            sprintf(buf,"errno:%d\n",errno);
            syslog(LOG_ERR,"服务端进程启动失败");
            exit(EXIT_FAILURE);
        }
        else
        {
            syslog(LOG_ERR,"子进程fork失败");
        }

    }
    return EXIT_SUCCESS;
}
 

二、IO多路复用

相关函数

测试例程

相关推荐
吠品11 分钟前
Wine 在 Linux 上运行 Windows 软件完整指南
java·linux·服务器
YXXY31324 分钟前
网络基础2(三)
网络
m24tyy1 小时前
常见空间测绘搜索引擎介绍和使用以及子域名的收集
网络·测试工具·搜索引擎
数据安全技术观察2 小时前
数据动态脱敏:让脱敏策略跟着数据目录走
大数据·网络·数据库
我爱cope2 小时前
【计算机网络 | 网络层1:网络层的职责:IP 协议究竟解决了什么问题?】
网络·tcp/ip·计算机网络
深念Y2 小时前
从 Windows 迁移到 Linux 开发环境的记录
linux·windows·链接·bun·ram·imdisk
AuTumn-L2 小时前
使用 SSH 密钥认证实现安全免密登录
服务器·安全·ssh
知无不研3 小时前
Linux I/O复用之epoll
linux·服务器·epoll·socket编程
dogstarhuang4 小时前
OpenAI GPT-5.6 降价后如何重算 API 账单?多模型路由与成本治理实战
服务器·网络·人工智能·大模型·api·ai应用开发·接口管理
苏宸啊4 小时前
linux网络编程udp服务器和客户端代码编写(echo版本和字典版本)
linux·网络