檢視原始碼 supervisor 行為 (stdlib v6.2)

通用監管者行為。

此行為模組提供了一個監管者,一個監管其他稱為子程序的程序。子程序可以是另一個監管者或一個工作程序。工作程序通常使用 gen_eventgen_servergen_statem 行為之一來實現。使用此模組實現的監管者具有一組標準的介面函數,並包含追蹤和錯誤報告的功能。監管者用於建立一個稱為監管樹的階層式程序結構,這是一種組織容錯應用程式的好方法。有關更多資訊,請參閱 OTP 設計原則中的監管者行為

監管者期望在回呼模組中指定要監管的子程序定義,並匯出預定義的函數集。

除非另有說明,否則如果指定的監管者不存在或指定了錯誤的參數,則此模組中的所有函數都會失敗。

監管原則

監管者負責啟動、停止和監控其子程序。監管者的基本概念是,它必須透過在必要時重新啟動子程序來保持其子程序存活。

監管者的子程序定義為子程序規格的列表。當監管者啟動時,會根據此列表從左到右依序啟動子程序。當監管者即將終止時,它會先以反向的啟動順序,從右到左終止其子程序。

監管者旗標

監管者的屬性由監管者旗標定義。監管者旗標的類型定義如下

sup_flags() = #{strategy => strategy(),           % optional
                intensity => non_neg_integer(),   % optional
                period => pos_integer(),          % optional
                auto_shutdown => auto_shutdown()} % optional

重新啟動策略

監管者可以使用上述映射中的 strategy 鍵來指定以下其中一種重新啟動策略

  • one_for_one - 如果一個子程序終止且要重新啟動,則只會影響該子程序。這是預設的重新啟動策略。

  • one_for_all - 如果一個子程序終止且要重新啟動,則會終止所有其他子程序,然後重新啟動所有子程序。

  • rest_for_one - 如果一個子程序終止且要重新啟動,則會終止「其餘」的子程序(也就是說,啟動順序中已終止的子程序之後的子程序)。然後重新啟動已終止的子程序以及其後的所有子程序。

  • simple_one_for_one - 簡化的 one_for_one 監管者,其中所有子程序都是相同程序類型的動態新增實例,也就是說,執行相同的程式碼。

    函數 delete_child/2restart_child/2 對於 simple_one_for_one 監管者無效,如果指定的監管者使用此重新啟動策略,則會傳回 {error,simple_one_for_one}

    函數 terminate_child/2 可以透過指定子程序的 pid/0 作為第二個參數,用於 simple_one_for_one 監管者下的子程序。如果改為使用子程序規格識別碼,則 terminate_child/2 會傳回 {error,simple_one_for_one}

    由於 simple_one_for_one 監管者可以有很多子程序,它會非同步關閉所有子程序。這表示子程序會平行進行清理,因此停止它們的順序未定義。

重新啟動強度和週期

為了防止監管者陷入子程序終止和重新啟動的無限迴圈,會使用上述映射中具有鍵 intensityperiod 的兩個整數值定義最大重新啟動強度。假設 intensity 的值為 MaxRperiod 的值為 MaxT,那麼,如果在 MaxT 秒內發生超過 MaxR 次的重新啟動,則監管者會終止所有子程序,然後自行終止。在這種情況下,監管者本身的終止原因將為 shutdownintensity 預設為 1,而 period 預設為 5

自動關閉

可以使用上述映射中的 auto_shutdown 鍵,將監管者設定為在 重要子程序 以退出原因 shutdown 終止時自動關閉。

  • never - 停用自動關閉。這是預設設定。

    auto_shutdown 設定為 never 時,將 significant 旗標設定為 true 的子程序規格被視為無效,且會被拒絕。

  • any_significant - 當任何重要子程序終止時,監管者會自行關閉,也就是說,當 transient 重要子程序正常終止時,或者當 temporary 重要子程序正常或異常終止時。

  • all_significant - 當所有重要子程序都終止時,監管者會自行關閉,也就是說,當最後一個活動的重要子程序終止時。與 any_significant 相同的規則適用。

有關更多資訊,請參閱 OTP 設計原則中監管者行為的自動關閉一節。

警告

自動關閉功能在 OTP 24.0 中出現,但使用此功能的應用程式也可以使用較舊的 OTP 版本編譯和執行。

但是,當使用早於自動關閉功能出現的 OTP 版本編譯此類應用程式時,會洩漏程序,因為它們所依賴的自動關閉不會發生。

如果實作者預期他們的應用程式可能會使用較舊的 OTP 版本編譯,則應採取適當的預防措施。

子程序規格

子程序規格的類型定義如下

child_spec() = #{id => child_id(),             % mandatory
                 start => mfargs(),            % mandatory
                 restart => restart(),         % optional
                 significant => significant(), % optional
                 shutdown => shutdown(),       % optional
                 type => worker(),             % optional
                 modules => modules()}         % optional

為了向後相容性,保留了舊的元組格式,請參閱 child_spec/0,但優先使用映射。

  • id 用於讓監管者在內部識別子程序規格。

    id 鍵是必要的。

    請注意,這個識別碼有時被稱為「名稱」。盡可能使用「識別碼」或「id」等術語,但為了保持向後相容性,仍然可以找到某些「名稱」的出現,例如在錯誤訊息中。

  • start 定義用於啟動子程序的函數呼叫。它必須是一個模組-函數-參數元組 {M,F,A},用作 apply(M,F,A)

    啟動函數必須建立並連結到子程序,而且必須傳回 {ok,Child}{ok,Child,Info},其中 Child 是子程序的 pid,而 Info 是監管者忽略的任何詞彙。

    如果由於某些原因無法啟動子程序,則啟動函數也可以傳回 ignore,在這種情況下,監管者會保留子程序規格(除非它是暫時子程序),但會忽略不存在的子程序。

    如果發生錯誤,該函數也可以傳回錯誤元組 {error,Error}

    請注意,不同行為模組的 start_link 函數符合上述要求。

    start 鍵是必要的。

  • restart 定義何時必須重新啟動已終止的子程序。permanent 子程序總是會重新啟動。temporary 子程序永遠不會重新啟動(即使監管者的重新啟動策略為 rest_for_oneone_for_all 且同級的終止導致暫時程序被終止)。只有當 transient 子程序異常終止時,才會重新啟動(也就是說,以 normalshutdown{shutdown,Term} 以外的退出原因終止)。

    restart 鍵是可選的。如果未指定,則預設為 permanent

  • significant 定義子程序是否被視為監管者的自動自行關閉的重要程序。

    重新啟動類型permanent 時,將此選項設定為 true 無效。此外,當 auto_shutdown 監管者旗標設定為 never 時,在監管者中啟動將此選項設定為 true 的子程序也被視為無效。

    significant 鍵是可選的。如果未指定,則預設為 false

  • shutdown 定義了子程序必須如何終止。brutal_kill 表示子程序會使用 exit(Child,kill) 無條件終止。整數的逾時值表示 supervisor 會呼叫 exit(Child,shutdown) 來告知子程序終止,然後等待子程序回傳原因為 shutdown 的結束訊號。如果在指定的毫秒數內沒有收到結束訊號,子程序會使用 exit(Child,kill) 無條件終止。

    如果子程序是另一個 supervisor,則必須將關閉時間設定為 infinity,以便給子樹足夠的時間關閉。

    警告

    對於類型為 supervisor 的子程序,將關閉時間設定為除了 infinity 以外的任何值,可能會導致競爭條件,其中相關的子程序會取消連結其自身的子程序,但在被終止之前未能終止它們。

    如果子程序是 worker,也可以將其設定為 infinity

    警告

    當子程序是 worker 時,請謹慎將關閉時間設定為 infinity。因為在這種情況下,監督樹的終止取決於子程序,它必須以安全的方式實作,並且其清理程序必須始終返回。

    請注意,所有使用標準 OTP 行為模組實作的子程序都會自動遵守關閉協定。

    shutdown 鍵是可選的。如果未指定,則如果子程序的類型為 worker,則預設為 5000;如果子程序的類型為 supervisor,則預設為 infinity

  • type 指定子程序是 supervisor 還是 worker。

    type 鍵是可選的。如果未指定,則預設為 worker

  • modules 在程式碼替換期間由釋出處理常式使用,以確定哪些程序正在使用特定模組。根據經驗法則,如果子程序是 supervisorgen_servergen_statem,則此值為一個包含一個元素 [Module] 的列表,其中 Module 是回呼模組。如果子程序是具有動態回呼模組集的事件管理器 (gen_event),則必須使用值 dynamic。有關釋出處理的更多資訊,請參閱 OTP 設計原則中的 釋出處理

    modules 鍵是可選的。如果未指定,則預設為 [M],其中 M 來自子程序的啟動 {M,F,A}

  • 在內部,supervisor 還會追蹤子程序的 pid Child,如果不存在 pid 則追蹤 undefined

另請參閱

gen_eventgen_statemgen_serversys

摘要

類型

不是 pid/0

保留 tuple 格式僅為向後相容性。建議使用 map;請參閱上方的更多詳細資訊。

用於 A(引數列表)的值 undefined 僅供內部 supervisor 使用。如果子程序的重新啟動類型為 temporary,則永遠不會重新啟動該程序,因此不需要儲存實際的引數列表。而是儲存值 undefined

保留 tuple 格式僅為向後相容性。建議使用 map;請參閱上方的更多詳細資訊。

在啟動 supervisor 時使用的名稱規範。請參閱函數 start_link/2,3 和下方類型 sup_ref/0

在尋址 supervisor 時使用的 supervisor 規範。請參閱 count_children/1delete_child/2get_childspec/2restart_child/2start_child/2terminate_child/2which_children/1 和上方類型 sup_name/0

回呼

每當使用 start_link/2,3 啟動 supervisor 時,新程序都會呼叫此函數,以了解重新啟動策略、最大重新啟動強度和子規格。

函數

以子規格列表作為引數,如果所有子規格在語法上都正確,則返回 ok,否則返回 {error,Error}

返回一個 屬性列表,其中包含 supervisor 的子規格和受管理程序的以下每個元素的計數

告知 supervisor SupRef 刪除由 Id 識別的子規格。對應的子程序必須未執行。使用 terminate_child/2 終止它。

返回在 supervisor SupRef 下由 Id 識別的子程序的子規格 map。返回的 map 包含所有鍵,包括強制鍵和可選鍵。

告知 supervisor SupRef 重新啟動對應於由 Id 識別的子規格的子程序。子規格必須存在,並且對應的子程序必須未執行。

動態將子規格新增至 supervisor SupRef,這會啟動對應的子程序。

建立一個無名的 supervisor 程序,作為監督樹的一部分。

建立一個 supervisor 程序,作為監督樹的一部分。

告知 supervisor SupRef 終止指定的子程序。

返回一個新建立的列表,其中包含屬於 supervisor SupRef 的所有子規格和子程序的相關資訊。

類型

連結到此類型

auto_shutdown()

檢視原始碼 (未匯出)
-type auto_shutdown() :: never | any_significant | all_significant.
-type child() :: undefined | pid().
連結到此類型

child_id()

檢視原始碼 (未匯出)
-type child_id() :: term().

不是 pid/0

連結到此類型

child_rec()

檢視原始碼 (未匯出)
-type child_rec() ::
          #child{pid :: child() | {restarting, pid() | undefined} | [pid()],
                 id :: child_id(),
                 mfargs :: mfargs(),
                 restart_type :: restart(),
                 significant :: significant(),
                 shutdown :: shutdown(),
                 child_type :: worker(),
                 modules :: modules()}.
-type child_spec() ::
          #{id := child_id(),
            start := mfargs(),
            restart => restart(),
            significant => significant(),
            shutdown => shutdown(),
            type => worker(),
            modules => modules()} |
          {Id :: child_id(),
           StartFunc :: mfargs(),
           Restart :: restart(),
           Shutdown :: shutdown(),
           Type :: worker(),
           Modules :: modules()}.

保留 tuple 格式僅為向後相容性。建議使用 map;請參閱上方的更多詳細資訊。

連結到此類型

children()

檢視原始碼 (未匯出)
-type children() :: {Ids :: [child_id()], Db :: #{child_id() => child_rec()}}.
連結到此類型

mfargs()

檢視原始碼 (未匯出)
-type mfargs() :: {M :: module(), F :: atom(), A :: [term()] | undefined}.

用於 A(引數列表)的值 undefined 僅供內部 supervisor 使用。如果子程序的重新啟動類型為 temporary,則永遠不會重新啟動該程序,因此不需要儲存實際的引數列表。而是儲存值 undefined

連結到此類型

modules()

檢視原始碼 (未匯出)
-type modules() :: [module()] | dynamic.
連結到此類型

restart()

檢視原始碼 (未匯出)
-type restart() :: permanent | transient | temporary.
連結到此類型

shutdown()

檢視原始碼 (未匯出)
-type shutdown() :: brutal_kill | timeout().
連結到此類型

significant()

檢視原始碼 (未匯出)
-type significant() :: boolean().
-type startchild_err() :: already_present | {already_started, Child :: child()} | term().
-type startchild_ret() ::
          {ok, Child :: child()} | {ok, Child :: child(), Info :: term()} | {error, startchild_err()}.
-type strategy() :: one_for_all | one_for_one | rest_for_one | simple_one_for_one.
-type sup_flags() ::
          #{strategy => strategy(),
            intensity => non_neg_integer(),
            period => pos_integer(),
            auto_shutdown => auto_shutdown()} |
          {RestartStrategy :: strategy(), Intensity :: non_neg_integer(), Period :: pos_integer()}.

保留 tuple 格式僅為向後相容性。建議使用 map;請參閱上方的更多詳細資訊。

-type sup_name() ::
          {local, Name :: atom()} | {global, Name :: term()} | {via, Module :: module(), Name :: any()}.

在啟動 supervisor 時使用的名稱規範。請參閱函數 start_link/2,3 和下方類型 sup_ref/0

  • {local,LocalName} - 使用 register/2 在本地將 supervisor 註冊為 LocalName

  • {global,GlobalName} - 使用 global:register_name/2 在全域將 supervisor 程序 ID 註冊為 GlobalName

  • {via,RegMod,ViaName} - 使用 RegMod 代表的註冊表註冊 supervisor 程序。RegMod 回呼需要匯出函式 register_name/2unregister_name/1whereis_name/1send/2,這些函式的行為與 global 中的對應函式相同。因此,{via,global,GlobalName} 是一個有效的參考,等同於 {global,GlobalName}

-type sup_ref() ::
          (Name :: atom()) |
          {Name :: atom(), Node :: node()} |
          {global, Name :: term()} |
          {via, Module :: module(), Name :: any()} |
          pid().

在尋址 supervisor 時使用的 supervisor 規範。請參閱 count_children/1delete_child/2get_childspec/2restart_child/2start_child/2terminate_child/2which_children/1 和上方類型 sup_name/0

它可以是

  • pid/0 - supervisor 的程序識別碼。

  • LocalName - supervisor 在本地註冊為 LocalName,使用 register/2

  • {Name,Node} - supervisor 在另一個節點上本地註冊。

  • {global,GlobalName} - supervisorglobal 中全域註冊。

  • {via,RegMod,ViaName} - supervisor 在替代的程序註冊表中註冊。註冊表回呼模組 RegMod 必須匯出函式 register_name/2unregister_name/1whereis_name/1send/2,這些函式的行為與 global 中的對應函式相同。因此,{via,global,GlobalName}{global,GlobalName} 相同。

-type worker() :: worker | supervisor.

回呼函式

-callback init(Args :: term()) -> {ok, {SupFlags :: sup_flags(), [ChildSpec :: child_spec()]}} | ignore.

每當使用 start_link/2,3 啟動 supervisor 時,新程序都會呼叫此函數,以了解重新啟動策略、最大重新啟動強度和子規格。

Args 是提供給啟動函式的 Args 引數。

SupFlags 是 supervisor 旗標,定義 supervisor 的重新啟動策略和最大重新啟動強度。[ChildSpec] 是有效子程序規格的列表,定義 supervisor 必須啟動和監控哪些子程序。請參閱先前章節 監管原則 中的討論。

請注意,當重新啟動策略為 simple_one_for_one 時,子程序規格列表必須只有一個子程序規格。(子程序規格識別碼會被忽略。)在初始化階段不會啟動任何子程序,但假設所有子程序都是使用 start_child/2 動態啟動的。

函式也可以回傳 ignore

請注意,此函式也可以作為程式碼升級程序的一部分呼叫。因此,此函式不應有任何副作用。有關 supervisor 的程式碼升級的詳細資訊,請參閱 OTP 設計原則中的「變更 Supervisor」章節。

函式

連結至此函式

check_childspecs(ChildSpecs)

檢視原始碼
-spec check_childspecs(ChildSpecs) -> Result
                          when ChildSpecs :: [child_spec()], Result :: ok | {error, Error :: term()}.

等效於 check_childspecs(ChildSpecs, undefined)

連結至此函式

check_childspecs(ChildSpecs, AutoShutdown)

檢視原始碼 (自 OTP 24.0 起)
-spec check_childspecs(ChildSpecs, AutoShutdown) -> Result
                          when
                              ChildSpecs :: [child_spec()],
                              AutoShutdown :: undefined | auto_shutdown(),
                              Result :: ok | {error, Error :: term()}.

以子規格列表作為引數,如果所有子規格在語法上都正確,則返回 ok,否則返回 {error,Error}

如果 AutoShutdown 引數不是 undefined,也會檢查給定的 auto_shutdown 選項是否允許子程序規格。

連結至此函式

count_children(SupRef)

檢視原始碼 (自 OTP R13B04 起)
-spec count_children(SupRef) -> PropListOfCounts
                        when
                            SupRef :: sup_ref(),
                            PropListOfCounts :: [Count],
                            Count ::
                                {specs, ChildSpecCount :: non_neg_integer()} |
                                {active, ActiveProcessCount :: non_neg_integer()} |
                                {supervisors, ChildSupervisorCount :: non_neg_integer()} |
                                {workers, ChildWorkerCount :: non_neg_integer()}.

返回一個 屬性列表,其中包含 supervisor 的子規格和受管理程序的以下每個元素的計數

  • specs - 子程序的總數,無論是否已終止。
  • active - 此 supervisor 管理的所有正在執行之子程序的計數。對於 simple_one_for_one supervisor,不會執行檢查以確保每個子程序仍然存活,儘管這裡提供的結果可能非常準確,除非 supervisor 嚴重超載。
  • supervisors - 在規格列表中標記為 child_type = supervisor 的所有子程序的計數,無論子程序是否仍然存活。
  • workers - 在規格列表中標記為 child_type = worker 的所有子程序的計數,無論子程序是否仍然存活。
連結至此函式

delete_child(SupRef, Id)

檢視原始碼
-spec delete_child(SupRef, Id) -> Result
                      when
                          SupRef :: sup_ref(),
                          Id :: child_id(),
                          Result :: ok | {error, Error},
                          Error :: running | restarting | not_found | simple_one_for_one.

告知 supervisor SupRef 刪除由 Id 識別的子規格。對應的子程序必須未執行。使用 terminate_child/2 終止它。

如果成功,此函式會回傳 ok。如果 Id 識別的子程序規格存在,但對應的子程序正在執行或即將重新啟動,則此函式會分別回傳 {error,running}{error,restarting}。如果 Id 識別的子程序規格不存在,則此函式會回傳 {error,not_found}

連結至此函式

get_childspec(SupRef, Id)

檢視原始碼 (自 OTP 18.0 起)
-spec get_childspec(SupRef, Id) -> Result
                       when
                           SupRef :: sup_ref(),
                           Id :: pid() | child_id(),
                           Result :: {ok, child_spec()} | {error, Error},
                           Error :: not_found.

返回在 supervisor SupRef 下由 Id 識別的子程序的子規格 map。返回的 map 包含所有鍵,包括強制鍵和可選鍵。

連結至此函式

restart_child(SupRef, Id)

檢視原始碼
-spec restart_child(SupRef, Id) -> Result
                       when
                           SupRef :: sup_ref(),
                           Id :: child_id(),
                           Result ::
                               {ok, Child :: child()} |
                               {ok, Child :: child(), Info :: term()} |
                               {error, Error},
                           Error :: running | restarting | not_found | simple_one_for_one | term().

告知 supervisor SupRef 重新啟動對應於由 Id 識別的子規格的子程序。子規格必須存在,並且對應的子程序必須未執行。

請注意,對於臨時子程序,當子程序終止時,子程序規格會自動刪除;因此,無法重新啟動此類子程序。

如果 Id 識別的子程序規格不存在,則此函式會回傳 {error,not_found}。如果子程序規格存在,但對應的程序已在執行,則此函式會回傳 {error,running}

如果子程序啟動函式回傳 {ok,Child}{ok,Child,Info},則 pid 會新增至 supervisor,且此函式會回傳相同的值。

如果子程序啟動函式回傳 ignore,則 pid 仍設定為 undefined,且此函式會回傳 {ok,undefined}

如果子程序啟動函式回傳錯誤元組或錯誤值,或者如果失敗,則此函式會回傳 {error,Error},其中 Error 是包含錯誤相關資訊的詞彙。

連結至此函式

start_child(Supervisor, ChildSpecOrExtraArgs)

檢視原始碼
-spec start_child(SupRef, ChildSpec) -> startchild_ret()
                     when SupRef :: sup_ref(), ChildSpec :: child_spec();
                 (SupRef, ExtraArgs) -> startchild_ret() when SupRef :: sup_ref(), ExtraArgs :: [term()].

動態將子規格新增至 supervisor SupRef,這會啟動對應的子程序。

對於 one_for_oneone_for_allrest_for_one supervisor,第二個引數必須是有效的子程序規格 ChildSpec。子程序會使用子程序規格中定義的啟動函式來啟動。

對於 simple_one_for_one supervisor,會使用 Module:init/1 中定義的子程序規格,且第二個引數必須是任意詞彙列表 ExtraArgs。接著會將 ExtraArgs 附加至現有的啟動函式引數來啟動子程序,也就是呼叫 apply(M, F, A++ExtraArgs),其中 {M,F,A} 是子程序規格中定義的啟動函式。

  • 如果已存在具有指定識別碼的子程序規格,則會捨棄 ChildSpec,並且此函式會根據對應的子程序是否正在執行,回傳 {error,already_present}{error,{already_started,Child}}
  • 如果子程序啟動函式回傳 {ok,Child}{ok,Child,Info},則子程序規格和 pid 會新增至 supervisor,且此函式會回傳相同的值。
  • 如果子程序啟動函式回傳 ignore,則如果它是 one_for_oneone_for_allrest_for_one supervisor,則子程序規格 ChildSpec 會新增至 supervisor,且 pid 會設定為 undefined。對於 simple_one_for_one supervisor,不會將任何子程序新增至 supervisor。此函式會回傳 {ok,undefined}

如果子程序啟動函式回傳錯誤元組或錯誤值,或者如果失敗,則會捨棄子程序規格,且此函式會回傳 {error,Error},其中 Error 是包含錯誤和子程序規格相關資訊的詞彙。

連結至此函式

start_link(Module, Args)

檢視原始碼
-spec start_link(Module, Args) -> startlink_ret() when Module :: module(), Args :: term().

建立一個無名的 supervisor 程序,作為監督樹的一部分。

等同於 start_link/3,不同之處在於 supervisor 程序不會 註冊

連結至此函式

start_link(SupName, Module, Args)

檢視原始碼
-spec start_link(SupName, Module, Args) -> startlink_ret()
                    when SupName :: sup_name(), Module :: module(), Args :: term().

建立一個 supervisor 程序,作為監督樹的一部分。

例如,此函式會確保 supervisor 連結至呼叫的程序 (其 supervisor)。

建立的 supervisor 程序會呼叫 Module:init/1,以找出重新啟動策略、最大重新啟動強度和子程序。為了確保同步啟動程序,start_link/2,3 不會回傳,直到 Module:init/1 回傳且所有子程序都已啟動。

  • 如果 SupName={local,Name},則 supervisor 會使用 register/2 在本地註冊為 Name
  • 如果 SupName={global,Name},則 supervisor 會使用 global:register_name/2 在全域註冊為 Name
  • 如果 SupName={via,Module,Name},則 supervisor 會使用 Module 代表的註冊表註冊為 NameModule 回呼必須匯出函式 register_name/2unregister_name/1send/2,這些函式的行為必須與 global 中的對應函式相同。因此,{via,global,Name} 是一個有效的參考。

Module 是回呼模組的名稱。

Args 是任何作為引數傳遞給 Module:init/1 的詞彙。

  • 如果成功建立 supervisor 及其子程序 (也就是說,如果所有子程序啟動函式都回傳 {ok,Child}{ok,Child,Info}ignore),則此函式會回傳 {ok,Pid},其中 Pid 是 supervisor 的 pid。
  • 如果已存在具有指定 SupName 的程序,則此函式會回傳 {error,{already_started,Pid}},其中 Pid 是該程序的 pid。
  • 如果 Module:init/1 回傳 ignore,則此函式也會回傳 ignore,且 supervisor 會以原因 normal 終止。
  • 如果 Module:init/1 失敗或返回不正確的值,此函數會返回 {error,Term},其中 Term 是一個包含錯誤資訊的詞語,且監管者會因 Term 的原因而終止。
  • 如果任何子程序啟動函數失敗或返回錯誤元組或錯誤的值,監管者首先會以 shutdown 的原因終止所有已啟動的子程序,然後終止自身並返回 {error, {shutdown, Reason}}
連結至此函式

terminate_child(SupRef, Id)

檢視原始碼
-spec terminate_child(SupRef, Id) -> Result
                         when
                             SupRef :: sup_ref(),
                             Id :: pid() | child_id(),
                             Result :: ok | {error, Error},
                             Error :: not_found | simple_one_for_one.

告知 supervisor SupRef 終止指定的子程序。

如果監管者不是 simple_one_for_one,則 Id 必須是子規範識別符。該程序(如果有的話)會被終止,除非它是臨時子程序,否則子規範會被監管者保留。子程序稍後可以由監管者重新啟動。也可以通過呼叫 restart_child/2 顯式重新啟動子程序。使用 delete_child/2 移除子規範。

如果子程序是臨時的,則一旦程序終止,子規範就會被刪除。這意味著 delete_child/2 沒有意義,並且 restart_child/2 不能用於這些子程序。

如果監管者是 simple_one_for_one,則 Id 必須是子程序的 pid/0。如果指定的程序處於活動狀態,但不是指定監管者的子程序,則函數會返回 {error,not_found}。如果指定的是子規範識別符而不是 pid/0,則函數會返回 {error,simple_one_for_one}

如果成功,該函數會返回 ok。如果不存在具有指定 Id 的子規範,則函數會返回 {error,not_found}

連結至此函式

which_children(SupRef)

檢視原始碼
-spec which_children(SupRef) -> [{Id, Child, Type, Modules}]
                        when
                            SupRef :: sup_ref(),
                            Id :: child_id() | undefined,
                            Child :: child() | restarting,
                            Type :: worker(),
                            Modules :: modules().

返回一個新建立的列表,其中包含屬於 supervisor SupRef 的所有子規格和子程序的相關資訊。

請注意,在記憶體不足的情況下,當監管許多子程序時呼叫此函數可能會導致記憶體不足異常。

以下資訊提供給每個子規範/程序

  • Id - 如子規範中定義,或對於 simple_one_for_one 監管者為 undefined
  • Child - 對應子程序的 pid,如果程序即將重新啟動則為原子 restarting,如果沒有這樣的程序則為 undefined
  • Type - 如子規範中定義。
  • Modules - 如子規範中定義。