2015-04-27 45 views
0

基于Libmongoose的服务器在终端上的Windows以及服务中运行良好。Linux守护进程 - 运行两次功能

现在,我将它移植到Linux。在终端中运行时它是完美的。现在,我想把它作为一个守护进程运行 - 它的工作原理,但令我惊讶的是它调用了所有的功能两次。我检查了PID,只有一个进程正在运行。这让我疯狂。的daemonizing代码如下:

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 
} 

现在,i之后调用内部的start_server()功能-functions被调用两次:

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年4月27日,23:06:39信息:启动服务器..

2015-04-27,23:06:41信息:Server Started!

2015-04-27,23:06:41信息:Server Started!

2015年4月27日,23时06分41秒的信息:侦听端口:8091

2015年4月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"; 

} 
+0

;永不比较==真;因为'真'可能是最不重要的任何值,而不是0而是比较!= false或甚至更好:'if(CommandArgs.at(“ - d”))' – user3629249

+0

您应该熟悉的最小示例在哪里? –

+0

在编写代码时,总是使用空格进行缩进,而不是制表符发布的代码清楚地显示了为什么制表符永远不会用于缩进。 – user3629249

回答

1

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

这可能会开始发生,你说,它如果功能 mg_create_server()一个,mg_set_option(),或mg_copy_listeners()修改out,设置silentModefalse,或以其他方式使得这会产生这样的结果发生变化。

+0

你说得对cout解决了问题。万分感谢! –