多進(jìn)程高并發(fā)設(shè)計(jì)框架建議根據(jù)cpu核心數(shù)量來(lái)設(shè)置子進(jìn)程的數(shù)量。建議將對(duì)應(yīng)某一進(jìn)程綁定到某一cpu上(cpu親緣性),以充分利用多核系統(tǒng)的并發(fā)處理能力。多個(gè)進(jìn)程在多個(gè)不同的核心上運(yùn)行,實(shí)現(xiàn)負(fù)載均衡。職責(zé)明確,管理進(jìn)程僅負(fù)責(zé)管理,工作進(jìn)程負(fù)責(zé)處理業(yè)務(wù)邏輯。
示例:
multip_process.c
代碼語(yǔ)言:C
#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h> <p>// 函數(shù)指針定義,返回void,參數(shù)為void<em> typedef void (</em>spawn_proc_pt)(void *data);</p><p>// 工作進(jìn)程的處理周期函數(shù) static void worker_process_cycle(void *data);</p><p>// 啟動(dòng)工作進(jìn)程 static void start_worker_processes(int n);</p><p>// 創(chuàng)建子進(jìn)程 pid_t spawn_process(spawn_proc_pt proc, void <em>data, char </em>name);</p><p>int main(int argc, char **argv) { // 啟動(dòng)4個(gè)工作進(jìn)程 start_worker_processes(4); // 管理子進(jìn)程 wait(NULL); }</p><p>// 啟動(dòng)子進(jìn)程 void start_worker_processes(int n) { int i = 0; for (i = n - 1; i >= 0; i--) { // 第一個(gè)參數(shù)為工作進(jìn)程的處理周期 spawn_process(worker_process_cycle, (void *)(intptr_t)i, "worker process"); } }</p><p>// 創(chuàng)建子進(jìn)程 pid_t spawn_process(spawn_proc_pt proc, void <em>data, char </em>name) { pid_t pid; pid = fork(); // 創(chuàng)建子進(jìn)程 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>// 設(shè)置CPU親緣關(guān)系,將進(jìn)程綁定在其中的一個(gè)核上 static void worker_process_init(int worker) { cpu_set_t cpu_affinity; // 多核高并發(fā)處理 CPU_ZERO(&cpu_affinity); // 參數(shù) - CPU編號(hào) - 掩碼地址 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; // 工作進(jìn)程初始化 worker_process_init(worker); // 干活 for (;;) { sleep(10); printf("pid %ld ,doing ...n", (long int)getpid()); } }
執(zhí)行:
補(bǔ)充:
查看進(jìn)程在CPU核心上的命令:
ps -eLo ruser,pid,lwp,psr,args
設(shè)置CPU親緣性后,可以發(fā)現(xiàn)每個(gè)子進(jìn)程對(duì)應(yīng)一個(gè)核心。若不設(shè)置,則存在進(jìn)程與核心之間的切換,進(jìn)程從一個(gè)核切換到另一個(gè)核,進(jìn)行拷貝與復(fù)制,從而浪費(fèi)了CPU的性能,降低了執(zhí)行效率。有關(guān)函數(shù)指針和typedef的結(jié)合運(yùn)用,請(qǐng)參考相關(guān)文章。