多進程高并發設計框架建議根據cpu核心數量來設置子進程的數量。建議將對應某一進程綁定到某一cpu上(cpu親緣性),以充分利用多核系統的并發處理能力。多個進程在多個不同的核心上運行,實現負載均衡。職責明確,管理進程僅負責管理,工作進程負責處理業務邏輯。
示例:
multip_process.c
代碼語言:C
#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h> <p>// 函數指針定義,返回void,參數為void<em> typedef void (</em>spawn_proc_pt)(void *data);</p><p>// 工作進程的處理周期函數 static void worker_process_cycle(void *data);</p><p>// 啟動工作進程 static void start_worker_processes(int n);</p><p>// 創建子進程 pid_t spawn_process(spawn_proc_pt proc, void <em>data, char </em>name);</p><p>int main(int argc, char **argv) { // 啟動4個工作進程 start_worker_processes(4); // 管理子進程 wait(NULL); }</p><p>// 啟動子進程 void start_worker_processes(int n) { int i = 0; for (i = n - 1; i >= 0; i--) { // 第一個參數為工作進程的處理周期 spawn_process(worker_process_cycle, (void *)(intptr_t)i, "worker process"); } }</p><p>// 創建子進程 pid_t spawn_process(spawn_proc_pt proc, void <em>data, char </em>name) { pid_t pid; pid = fork(); // 創建子進程 switch (pid) { case -1: fprintf(stderr, "fork() failed while spawning "%s"n", name); return -1; case 0: proc(data); return 0; default: break; } printf("start %s %ldn", name, (long int)pid); return pid; }</p><p>// 設置CPU親緣關系,將進程綁定在其中的一個核上 static void worker_process_init(int worker) { cpu_set_t cpu_affinity; // 多核高并發處理 CPU_ZERO(&cpu_affinity); // 參數 - CPU編號 - 掩碼地址 CPU_SET(worker % CPU_SETSIZE, &cpu_affinity); // sched_setaffinity if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_affinity) == -1) { fprintf(stderr, "sched_setaffinity() failedn"); } }</p><p>void worker_process_cycle(void *data) { int worker = (intptr_t)data; // 工作進程初始化 worker_process_init(worker); // 干活 for (;;) { sleep(10); printf("pid %ld ,doing ...n", (long int)getpid()); } }
執行:
補充:
查看進程在CPU核心上的命令:
ps -eLo ruser,pid,lwp,psr,args
設置CPU親緣性后,可以發現每個子進程對應一個核心。若不設置,則存在進程與核心之間的切換,進程從一個核切換到另一個核,進行拷貝與復制,從而浪費了CPU的性能,降低了執行效率。有關函數指針和typedef的結合運用,請參考相關文章。