2017-02-27 67 views
-1

我設法使用下面的代碼來建立一個守護進程。我的問題是我想創建一個腳本來啓動這個守護進程並將守護進程PID存儲在/var/run/mydaemon.pid中。此外,第二個腳本通過訪問存儲的mydaemon.pid文件來停止守護進程。簡單的腳本來啓動一個守護進程的商店pid

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

#define EXIT_SUCCESS 0 
#define EXIT_FAILURE 1 

static void daemonize(void) 
{ 
    pid_t pid, sid; 

    /* already a daemon */ 
    if (getppid() == 1) return; 

    /* Fork off the parent process */ 
    pid = fork(); 
    if (pid < 0) { 
     exit(EXIT_FAILURE); 
    } 
    /* If we got a good PID, then we can exit the parent process. */ 
    if (pid > 0) { 
     exit(EXIT_SUCCESS); 
    } 

    /* At this point we are executing as the child process */ 

    /* Change the file mode mask */ 
    umask(0); 

    /* Create a new SID for the child process */ 
    sid = setsid(); 
    if (sid < 0) { 
     exit(EXIT_FAILURE); 
    } 

    /* Change the current working directory. This prevents the current 
     directory from being locked; hence not being able to remove it. */ 
    if ((chdir("/")) < 0) { 
     exit(EXIT_FAILURE); 
    } 

    /* Redirect standard files to /dev/null */ 
    freopen("/dev/null", "r", stdin); 
    freopen("/dev/null", "w", stdout); 
    freopen("/dev/null", "w", stderr); 
} 

int main(int argc, char *argv[]) { 
    daemonize(); 

    /* Now we are a daemon -- do the work for which we were paid */ 


    return 0; 
} 

我環顧四周,似乎無法找到示例代碼來幫助我。我得到的最接近的東西是你在下面看到的東西。但它不起作用。

#!/bin/sh 


set -e 

# Must be a valid filename 
NAME=mydaemon 
PIDFILE=/var/run/$NAME.pid 


DAEMON=/home/me/mydaemon/mydaemon/a.out 


export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" 

case "$1" in 
    start) 
     echo -n "Starting daemon: "$NAME 
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON 
     echo "." 
    ;; 
    *) 
    echo "Usage: "$1" {start}" 
    exit 1 
esac 

exit 0 
+1

「*它沒有工作。*」是或多或少的價值麻煩報告可以給。 – alk

+0

讓守護進程調用'getpid()',並將結果打印到'/ var/run/mydeamon.pid'? – alk

+0

相關:http://stackoverflow.com/q/3957242/694576 http://stackoverflow.com/q/24662327/694576 – alk

回答

-2

你可以在父的C程序退出回電 和$讀取值回孩子的PID?調用腳本的變量。

./myDeamon

childPid = $?

+1

'$?'返回的狀態只能存儲最多255個值; PIDs覆蓋範圍更廣。 –

0

在寫入守護進程代碼後,您無法確定剛剛啓動的守護進程的PID,因爲該信息不可用。如果您在後臺運行程序(如果使用./mydaemon &,則$!將報告PID),但父進程信息將可用,但該進程剛剛退出,而使另一個進程運行。

您需要守護程序代碼的幫助;父代碼應在退出之前報告子進程的PID。

/* If we got a good PID, report child PID and exit the parent process. */ 
if (pid > 0) { 
    printf("%d\n", (int)pid); 
    exit(EXIT_SUCCESS); 
} 

現在你可以使用:

NAME=mydaemon 
# PIDFILE=/var/run/$NAME.pid 
# DAEMON=/home/me/mydaemon/mydaemon/a.out 

pidfile="/var/run/mydaemon.pid" 
pid=$($NAME) 
if [ -n "$pid" ] 
then 
    echo "$pid" > "$pidfile" 
else 
    echo "$0: failed to launch daemonized process '$NAME'" >&2 
    exit 1 
fi 

這依賴於代碼(守護進程)不會寫到標準輸出,除非它是成功的分叉。如果需要報告任何錯誤,它可以寫入標準錯誤。

+0

嗨喬納森·勒弗勒謝謝!當我運行腳本時,我得到/.startrevd.sh:未能啓動守護程序進程''有什麼我錯過了? – xxFlashxx

+0

我不知道 - 可能。或者我錯過了什麼。假設你從命令行運行'mydaemon';你有沒有得到一個進程號碼報告?如果是這樣,假設報告的數字是12345,你能看到'ps -fp 12345'的過程嗎?你能發送一個信號給它 - 「殺死12345」嗎?如果這些導致問題,那麼你可能沒有正確修改你的守護進程。您可能需要將'sh -x startrevd.sh'的輸出添加到您的問題中 - 請注意單詞_add_(保留大部分信息不變)。 –

+0

是的,例如當我運行'。/守護進程時,12345會顯示出來,但是當我輸入ps'-fp 12345'時,它是空的... – xxFlashxx