Nginx 通過覆蓋 argv 內存區,讓 ps 顯示自定義進程名(如 nginx: worker process),便於運維識別。
argv 指針數組地址與 argv[0] 末尾地址 os_argv_last。setproctitle() 將新標題拷貝到 argv[0],剩餘空間填空格,argv[1]=NULL 截斷後續參數顯示。#include#include #include char **os_argv; char *os_argv_last; void init_setproctitle(void) { os_argv_last = os_argv[0]; for (int i = 0; os_argv[i]; ++i) { if (os_argv_last == os_argv[i]) os_argv_last = os_argv[i] + strlen(os_argv[i]) + 1; } os_argv_last += strlen(os_argv_last); // 指向環境變量區起始 } void setproctitle(const char *title) { os_argv[1] = NULL; char *p = strncpy((char *)os_argv[0], title, strlen(title)); p += strlen(title); if (os_argv_last > p) memset(p, ' ', os_argv_last - p); } void save_argv(int argc, char *const *argv) { os_argv = (char **)argv; } void worker_process() { setproctitle("mynginx: worker process"); for (;;) { sleep(1); printf("worker pid=%d\n", getpid()); } } void dispatcher_process() { setproctitle("mynginx: dispatcher process"); for (;;) { sleep(1); printf("\tdispatcher pid=%d\n", getpid()); } } int main(int argc, char **argv) { save_argv(argc, argv); init_setproctitle(); printf("master pid=%d\n", getpid()); // 啟動 3 個 worker for (int i = 0; i < 3; ++i) { if (fork() == 0) worker_process(); } // 啟動 1 個 dispatcher if (fork() == 0) dispatcher_process(); // Master 進程主循環 for (;;) sleep(1); return 0; }
$ gcc mynginx.c -o mynginx $ ./mynginx master pid=20553 worker pid=20554 worker pid=20555 worker pid=20556 dispatcher pid=20557
$ ps -ef | grep mynginx test 20553 20463 0 23:54 pts/0 00:00:00 ./mynginx test 20554 20553 0 23:54 pts/0 00:00:00 mynginx: worker process test 20555 20553 0 23:54 pts/0 00:00:00 mynginx: worker process test 20556 20553 0 23:54 pts/0 00:00:00 mynginx: worker process test 20557 20553 0 23:54 pts/0 00:00:00 mynginx: dispatcher process
| 點 | 說明 |
|---|---|
| fork 後關閉無用 fd | 真實 Nginx 中子進程關閉聽套接字,父進程關閉連接套接字;Demo 簡化省略 |
| 信號處理 | Master 需處理 SIGCHLD 回收僵屍進程、SIGHUP 平滑重載;Demo 未演示 |
| 共享內存/鎖 | 多 Worker accept 同一端口需 accept_mutex 序列化;Demo 未涉及網絡 |
| argv 內存佈局 | argv 緊鄰 environ,修改 argv 區不影響環境變量;跨平台需注意對齊 |
epoll/kqueue 事件循環實現真正的 HTTP 服務。