Linux 守护进程 - 运行函数两次

Linux Daemon - runs functions twice

本文关键字:两次 函数 守护 进程 运行 Linux      更新时间:2023-10-16

我的基于Libmongoose的服务器在终端和服务中的Windows上运行良好。

现在,我正在将其移植到Linux上。在终端中运行时,它非常完美。现在,我想将其作为守护程序运行 - 它可以工作,但令我惊讶的是,它调用了所有函数两次。我检查了PID,只有一个进程正在运行。这让我发疯。守护代码如下所示:

if(CommandArgs.at("-d") == "true")
{
    #if __linux
    pid_t pid, sid;
    pid = fork();
    if (pid < 0) {
       exit(EXIT_FAILURE);
    }
    if (pid > 0) {
       exit(EXIT_SUCCESS);
    }
    umask(0);
    sid = setsid();
    if (sid < 0) {
       exit(EXIT_FAILURE);
    }
    /* Change the current working directory */
    if ((chdir("/")) < 0) {
       exit(EXIT_FAILURE);
    }
    /* Close out the standard file descriptors */
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    if(start_server() == false)
    {
        exit(EXIT_FAILURE);
    }
    else
    {
        signal(SIGHUP, signal_handler);
        signal(SIGTERM, signal_handler);
        signal(SIGINT, signal_handler);
        signal(SIGQUIT, signal_handler);
        pause();
    }
    //exit(EXIT_SUCCESS);
    return 0;
    #endif
}

现在,在我调用start_server()函数之后,里面的函数被调用了两次:

static bool start_server()
{
    try{
        // invoked once as expected
        MyLogger(2, "Info: Starting  Server ...");  
        #ifdef _WIN32
        mutex = CreateMutex( NULL, FALSE, NULL); 
        #else
        pthread_mutex_init(&mutex, NULL);  
                #endif
        for(int i = 0; i < serverConf.totalThreads; i++)
        {       
                        server[i] = mg_create_server(NULL, event_handler);
            if(i==0)
            {
                const char * error_msg = mg_set_option(server[0], "listening_port", serverConf.port.c_str());
                 if (error_msg != NULL) {
                    MyLogger(1,"Error: Cannot bind to the port:",serverConf.port.c_str());
                    return false;
                }
            }
            else
            {
                mg_copy_listeners(server[0], server[i]);
                        }
        }
        // Now all the logging happening twice
        ServerStarted = true;
        for(int i = 0; i < serverConf.totalThreads; i++)
        {
            mg_start_thread(serve, server[i]);
        }
        // server1 goes to separate thread, server 2 runs in main thread.
        // IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER.
        MyLogger(2, "Info: Server Started!");  // why was i logged twice
        MyLogger(2, "Info: Listening on port:",  mg_get_option(server[0], "listening_port")); // why was i logged twice
    }
    catch(std::exception& e)
    {
        return false;
    }
    return true;
}

现在日志是:

2015-04-27, 23:06:39 信息: 启动服务器..

2015-04-27, 23:06:41 信息: 服务器已启动!

2015-04-27, 23:06:41 信息: 服务器已启动!

2015-04-27, 23:06:41 信息: 侦听端口: 8091

2015-04-27, 23:06:41 信息: 侦听端口: 8091

void MyLogger(int level, const char* msg1)
{
    if(level > LogLevel)
    {
        return;
    }
    string time = currentDateTime();
    std::ofstream out(LogFilePath.c_str(), std::fstream::app);
        if(silentMode == false)
    {
         cout<<"n"<<time<<" "<<msg1<<"n";
    }
    out<<"n"<<time<<" "<<msg1<<"n";
}

似乎消息很可能被函数MyLogger()复制。 如果silentMode == false,它将向两个流打印相同的消息,但它们实际上可能是同一个流,否则两个流的输出最终可能会重定向到同一位置。

这可能会在您说的地方开始发生,如果其中一个函数 mg_create_server()mg_set_option()mg_copy_listeners()修改out,将silentMode设置为false,或以其他方式进行更改以产生这样的结果。