Skip to content

Commit

Permalink
Add docs on fork w/o exec
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesge committed Nov 15, 2019
1 parent c7cd158 commit 1a3bfb9
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
11 changes: 11 additions & 0 deletions docs/cn/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,17 @@ server端会自动尝试其支持的协议,无需用户指定。`cntl->protoco

如果你有更多的协议需求,可以联系我们。

# fork without exec
一般来说,[fork](https://linux.die.net/man/3/fork)出的子进程应尽快调用[exec](https://linux.die.net/man/3/exec)以重置所有状态,中间只应调用满足async-signal-safe的函数。这么使用fork的brpc程序在之前的版本也不会有问题。

但在一些场景中,用户想直接运行fork出的子进程,而不调用exec。由于fork只复制其调用者的线程,其余线程便随之消失了。对应到brpc中,bvar会依赖一个sampling_thread采样各种信息,在fork后便消失了,现象是很多bvar归零。

最新版本的brpc会在fork后重建这个线程(如有必要),从而使bvar在fork后能正常工作,再次fork也可以。已知问题是fork后cpu profiler不正常。然而,这并不意味着用户可随意地fork,不管是brpc还是上层应用都会大量地创建线程,它们在fork后不会被重建,因为:
* 大部分fork会紧接exec,浪费了重建
* 给代码编写带来很多的麻烦和复杂度

brpc的策略是按需创建这类线程,同时fork without exec必须发生在所有可能创建这些线程的代码前。具体地说,至少**发生在初始化所有Server/Channel/应用代码前**,越早越好,不遵守这个约定的fork会导致程序不正常。另外,不支持fork without exec的lib相当普遍,最好还是避免这种用法。

# 设置

## 版本
Expand Down
11 changes: 11 additions & 0 deletions docs/en/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,17 @@ Server detects supported protocols automatically, without assignment from users.

If you need more protocols, contact us.

# fork without exec
In general, [forked](https://linux.die.net/man/3/fork) subprocess should call [exec](https://linux.die.net/man/3/exec) ASAP, before which only async-signal-safe functions should be called. brpc programs using fork like this should work correctly even in previous versions.

But in some scenarios, users continue the subprocess without exec. Since fork only copies its caller's thread, which causes other threads to disappear after fork. In the case of brpc, bvar depends on a sampling_thread to sample various information, which disappears after fork and causes many bvars to be zeros.

Latest brpc re-creates the thread after fork(when necessary) to make bvar work correctly, and can be forked again. A known problem is that the cpu profiler does not work after fork. However users still can't call fork at any time, since brpc and its applications create threads extensively, which are not re-created after fork:
* most fork continues with exec, which wastes re-creations
* bring too many troubles and complexities to the code

brpc's strategy is to create these threads on demand and fork without exec should happen before all code that may create the threads. Specifically, **fork without exec should happen before initializing all Servers/Channels/Applications, earlier is better. fork not obeying this causes the program dysfunctional. BTW, fork without exec better be avoided because many libraries do not support it.

# Settings

## Version
Expand Down

0 comments on commit 1a3bfb9

Please sign in to comment.