1. 程式人生 > >Win32 守護程序實現-- ACL 原始碼分析

Win32 守護程序實現-- ACL 原始碼分析

  1. 以deamon方式啟動父程序,主要是這二個介面
  2. void acl_proctl_deamon_init
  3. void proctl_monitor_loop
  4. 在檔案 acl_proctl.c 中
  5. void acl_proctl_deamon_init(const char *progname)
    {
        acl_pthread_attr_t attr;
        acl_pthread_t tid;

        var_progname = acl_mystrdup(progname);
        proctl_start_init(var_progname);      //
        acl_pthread_attr_init(&attr);
        (void) acl_pthread_attr_setdetachstate(&attr, 1);
        acl_pthread_create(&tid, &attr, proctl_monitor_thread, NULL);//
    }
 
1) proctl_start_init(var_progname); 主要是完成如下

    __sem_handle = CreateSemaphore(NULL, 0, 1024, NULL);   //建立訊號燈允許1024個子程序
    handles_add(__sem_handle);                             //增加到handle 陣列 後面用到
2)proctl_monitor_thread 執行緒函式
呼叫關係:
proctl_monitor_loop-->proctl_monitor_main-->proctl_monitor_cmd_start-
->proctl_msg_push(msg)

主要完成本地埠bind,listen,accept, 進入recv迴圈,收到要啟動的子程序資訊。這裡要說明一下 proctld.exe -d START {path}/proctlc.exe的實現,這裡會socket方式 連線到proctld.exe ,告知deamon程序要啟動的子程序的資訊,路徑、檔名等。然後此程序收到服務端(proctld.exe)響應後就退出了。服務端將收到的資訊構造成“msg”,proctl_msg_push(msg)放到了佇列中,然後ReleaseSemaphore(__sem_handle, 1, NULL); 發出訊號
,這是執行緒函式完成功能。

那主執行緒呢?看proctl_monitor_loop

void acl_proctl_daemon_loop()
{
    const char *myname = "acl_proctl_daemon_loop";
    time_t tm_start, tm_end;

    while (1) {
        tm_start = time(NULL);
        proctl_service_wait();              // --> proctl_service_wait(void)
        proctl_service_join();              //****

        tm_end = time(NULL);

        if (tm_end - tm_start <= 1) {
            acl_msg_warn("%s(%d): start process too fast, sleep 2 second",
                myname, __LINE__);
            sleep(2);
        }
    }
}

int proctl_service_wait(void)
  1. {
        const char *myname = "proctl_service_wait";
        DWORD timeout = 1000 * 2, ret;
        char  ebuf[256];
        HANDLE handle_sem;
        if (__cur_handle == 0)
            return (0);
        /* Create the semaphore, with max value 32K */
        handle_sem = CreateSemaphore(NULL, 0, 32 * 1024, NULL);
        while (1) {
            ret = WaitForMultipleObjects(__cur_handle, __handles, FALSE, timeout);  //接收到上面提到的發出的訊號
            if (ret == WAIT_OBJECT_0) {
                proctl_msg_main();
            } else 
  2.         .......
        }
        return (0);
    }
  3. proctl_msg_main 函式
  4. 呼叫關係如下
  5.             acl_fifo_pop-->proctl_service_start()-->proctl_service_add(service);
  6.                               proctl_service_start(service)-->handles_add(service->hProcess);
  功能:從佇列中取出訊息,啟動子程序。



int proctl_service_join(void)
{
    const char *myname = "proctl_service_join";
    PROCTL_SERVICE *service;
    HANDLE hProcess;
    DWORD status;
    int   i;
    char  ebuf[256];

    for (i = 0; i < __cur_handle; i++) {
        hProcess = __handles[i];
        if (hProcess == INVALID_HANDLE_VALUE)
            service = proctl_service_find(hProcess);
        if (service == NULL) {
            if (hProcess == __sem_handle)
                continue;
        }

        status = 0;
        if (!GetExitCodeProcess(hProcess, &status)) {  //不斷獲得子程序的狀態,若停止了就重新啟動
            if (proctl_service_restart(service) < 0)
                proctl_service_stopped(service);
        } else if (status == 0) {
            proctl_service_stopped(service);
        } else if (status != STILL_ACTIVE) {
            if (proctl_service_restart(service) < 0)
                proctl_service_stopped(service);
        }
        /* else: STILL_ACTIVE */
    }

    return (0);
}
  1. ---------------------------------------------------------------
  2. ---------------------------------------------------------------
  3. //子程序程式碼
  4. 主要函式void acl_proctl_child(const char *progname, void (*onexit_fn)(void *), void *arg);
    子程序在啟動時會用local_listenacl_vstream_accept,acl_vstream_gets_nonl等函式bind,accept,recv與父程序進行socket連線,在輸入命令proctld.exe -d STOP {path}/proctld.exe時,父程序需要主動連線到對應的子程序,然後傳送“STOP”命令給子程序,由子程序自己結束自己,而不是父程序直接結束子程序,這一點很不錯,可以由子程序來選擇自己適當的停止或重新等操作。

    到此為止,將win32 下ACL watch dog 機制簡單的理順了一下。但是這樣做法也有個問題,若是在一臺沒有網絡卡的機器上執行,因需要bind ip和port, 所以會不成功。那麼是不是就失效了,雖然現在很少有這種情況。唉,還是linux 下舒服。

可以執行 proctld.exe -d LIST 列出當前正在執行的子程序,執行 proctld.exe -d PROBE {path}/proctld.exe 判斷子程序是否在執行,執行 proctld.exe -d STOP {path}/proctld.exe 讓守護父程序停止子程序,執行 proctld.exe -d QUID 使守護程序停止所有子程序並自動退出。

相關推薦

Win32 守護程序實現-- ACL 原始碼分析

以deamon方式啟動父程序,主要是這二個介面void acl_proctl_deamon_initvoid proctl_monitor_loop在檔案 acl_proctl.c 中void acl_proctl_deamon_init(const char *progname) {     acl_pt

Java_59_陣列_模擬ArrayList容器的底層實現JDK原始碼分析程式碼

package cn.pmcse.myCollection; public class ArrayList {     private Object[] value;     private    in

java中List介面的實現類 ArrayList,LinkedList,Vector 的區別 list實現原始碼分析

java面試中經常被問到list常用的類以及內部實現機制,平時開發也經常用到list集合類,因此做一個原始碼級別的分析和比較之間的差異。 首先看一下List介面的的繼承關係: list介面繼承Col

[五]類載入機制雙親委派機制 底層程式碼實現原理 原始碼分析 java類載入雙親委派機制是如何實現

Launcher啟動類 本文是雙親委派機制的原始碼分析部分,類載入機制中的雙親委派模型對於jvm的穩定執行是非常重要的 不過原始碼其實比較簡單,接下來簡單介紹一下 我們先從啟動類說起 有一個Launcher類   sun.misc.Launcher; 仔細看下這簡

Spring實現AOP原始碼分析

Aop又叫面向切面程式設計,它的作用就是管理分散在整個應用中的變動。這句話理解起來有點抽象,舉個例子,比如我想在多個方法中加一些列印日誌,看下這些方法耗時如何,這些日誌資訊就是程式中的變動,而且是分散在各個不同的方法中的。如果我一個一個方法中去加日誌資訊的話,方

Java----- ArrayList構造、add、remove、clear方法實現原理原始碼分析

一.ArrayList內部的實現方式 ArrayList內部是通過Object[]實現的。 二.原始碼分析: (1).構造方法 public ArrayList() { array = EmptyArray.OBJECT; } p

WiFiAp探究實錄--功能實現原始碼分析

接下來要更新的博文是WiFi熱點相關的,更新時間為8月1號–8月30號之間。看到此博文的開發者們,如果有關於WiFi熱點的任何疑問可留言,最終會將值得研究的問題以及我已經研究出來的問題更新在博文上。 Android虐我千百遍,我待Android如初戀。

Linux C 守護程序實現後臺執行nohup效果

守護程序(Daemon)是執行在後臺的一種特殊程序。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護程序是一種很有用的進 程。Linux的大多數伺服器就是用守護程序實現的。比如,Internet伺服器inetd,Web伺服器httpd等。同時,守護

java LinkedList 底層實現原始碼分析

日常開場吹牛 LinkedList作為List集合的一種實現類(如果需要了解集合的繼承體系可以參考我另一篇文章《用幾張圖捋完集合的繼承實現關係》),其中和ArrayList的底層實現方式的不同在於,ArrayList的底層是由陣列來實現,那麼這樣的底層就決定了ArrayLi

阿里巴巴Dubbo實現原始碼分析

1.     Dubbo概述 Dubbo是阿里巴巴開源出來的一個分散式服務框架,致力於提供高效能和透明化的RPC遠端服務呼叫方案,以及作為SOA服務治理的方案。它的核心功能包括: #remoting: 遠端通訊基礎,提供對多種NIO框架抽象封裝,包括“同步轉非同步”和“請求

後臺守護程序實現coredump

1.在/etc/profile中加入以下一行,這將允許生成coredump檔案 ulimit-c unlimited 2. 在rc.local中加入以下一行,這將使程式崩潰時生成的coredump檔案位於/data/coredump/目錄下: echo "/bin/esun

Flink中Periodic水印和Punctuated水印實現原理(原始碼分析)

在使用者程式碼中,我們設定生成水印和事件時間的方法assignTimestampsAndWatermarks()中這裡有個方法的過載 我們傳入的物件分為兩種 AssignerWithPunctuatedWatermarks(可以理解為每條資料都會產生水印,如果不想產生水印,返回一個null的水印) Assig

Spring Boot從入門到精通(五)多資料來源配置實現原始碼分析

多資料來源配置在專案軟體中是比較常見的開發需求,Spring和Spring Boot中對此都有相應的解決方案可供大家參考。在Spring Boot中,如MyBatis、JdbcTemplate以及Jpa都可以配置多資料來源。 本文在前一篇“Spring Boot從入門到精通(四)連線MySQL資料庫(附原始碼

多執行緒高併發程式設計(11) -- 非阻塞演算法實現ConcurrentLinkedQueue原始碼分析

  一.背景   要實現對佇列的安全訪問,有兩種方式:阻塞演算法和非阻塞演算法。阻塞演算法的實現是使用一把鎖(出隊和入隊同一把鎖ArrayBlockingQueue)和兩把鎖(出隊和入隊各一把鎖LinkedBlockingQueue)來實現;非阻塞演算法使用自旋+CAS實現。   今天來探究下使用非阻塞演算法

多執行緒高併發程式設計(12) -- 阻塞演算法實現ArrayBlockingQueue原始碼分析(1)

一.前言   前文探究了非阻塞演算法的實現ConcurrentLinkedQueue安全佇列,也說明了阻塞演算法實現的兩種方式,使用一把鎖(出隊和入隊同一把鎖ArrayBlockingQueue)和兩把鎖(出隊和入隊各一把鎖LinkedBlockingQueue)來實現,今天來探究下ArrayBlocking

多執行緒高併發程式設計(12) -- 阻塞演算法實現ArrayBlockingQueue原始碼分析

一.前言   前文探究了非阻塞演算法的實現ConcurrentLinkedQueue安全佇列,也說明了阻塞演算法實現的兩種方式,使用一把鎖(出隊和入隊同一把鎖ArrayBlockingQueue)和兩把鎖(出隊和入隊各一把鎖LinkedBlockingQueue)來實現,今天來探究下ArrayBlocking

手動實現一個單詞統計MapReduce程序與過程原理分析

Hadoop MapReduce Java [toc] 手動實現一個單詞統計MapReduce程序與過程原理分析 前言 我們知道,在搭建好hadoop環境後,可以運行wordcount程序來體驗一下hadoop的功能,該程序在hadoop目錄下的share/hadoop/mapreduce目錄中

Dubbo原始碼分析:Dubbo自己實現的IOC

  在建立自適應例項時,都會呼叫ExtensionLoader的injectExtension方法: @SuppressWarnings("unchecked") private T createAdaptiveExtension() { try {

【Android】原始碼分析 - LRUCache快取實現原理

一、Android中的快取策略 一般來說,快取策略主要包含快取的新增、獲取和刪除這三類操作。如何新增和獲取快取這個比較好理解,那麼為什麼還要刪除快取呢?這是因為不管是記憶體快取還是硬碟快取,它們的快取大小都是有限的。當快取滿了之後,再想其新增快取,這個時候就需要刪除一些舊的快取

區塊鏈教程Fabric1.0原始碼分析Peer peer channel命令及子命令實現

  區塊鏈教程Fabric1.0原始碼分析Peer peer channel命令及子命令實現,2018年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁、迴歸理性,表面上看相關人才需求與身價似乎正在回落。但事實上,正是初期泡沫的漸退,讓人們更多的關注點放在了區塊鏈真正的技術之上。 Fabric1.0原始碼筆記之P