程管理:從原理到實(shí)踐全面解析)
1. 進(jìn)程操作系統(tǒng)的基本執(zhí)行單元在Linux系統(tǒng)中進(jìn)程Process是程序執(zhí)行時(shí)的一個(gè)實(shí)例也是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位。當(dāng)我們運(yùn)行一個(gè)程序時(shí)操作系統(tǒng)會(huì)為其創(chuàng)建一個(gè)進(jìn)程分配內(nèi)存空間、文件描述符等資源并開(kāi)始執(zhí)行程序代碼。1.1 進(jìn)程與程序的區(qū)別很多初學(xué)者容易混淆進(jìn)程和程序的概念。簡(jiǎn)單來(lái)說(shuō)程序是存儲(chǔ)在磁盤(pán)上的可執(zhí)行文件它包含了一系列指令和數(shù)據(jù)而進(jìn)程則是這些指令在內(nèi)存中的實(shí)際執(zhí)行過(guò)程。一個(gè)程序可以對(duì)應(yīng)多個(gè)進(jìn)程比如同時(shí)打開(kāi)多個(gè)終端窗口運(yùn)行同一個(gè)程序而一個(gè)進(jìn)程只能對(duì)應(yīng)一個(gè)程序。舉個(gè)例子/usr/bin/ls是一個(gè)程序文件當(dāng)你在終端輸入ls命令時(shí)操作系統(tǒng)會(huì)創(chuàng)建一個(gè)新的進(jìn)程來(lái)執(zhí)行這個(gè)程序。如果你同時(shí)在兩個(gè)終端窗口都運(yùn)行l(wèi)s命令那么系統(tǒng)中就會(huì)有兩個(gè)獨(dú)立的ls進(jìn)程在運(yùn)行。1.2 進(jìn)程的基本特征Linux進(jìn)程具有以下幾個(gè)關(guān)鍵特征動(dòng)態(tài)性進(jìn)程是程序的一次執(zhí)行過(guò)程它有創(chuàng)建、運(yùn)行、暫停、終止等生命周期并發(fā)性多個(gè)進(jìn)程可以在單個(gè)處理器上并發(fā)執(zhí)行通過(guò)時(shí)間片輪轉(zhuǎn)獨(dú)立性每個(gè)進(jìn)程都有自己獨(dú)立的地址空間和系統(tǒng)資源異步性進(jìn)程以不可預(yù)知的速度向前推進(jìn)結(jié)構(gòu)性每個(gè)進(jìn)程都有特定的數(shù)據(jù)結(jié)構(gòu)來(lái)描述其狀態(tài)和資源占用情況2. 進(jìn)程控制塊PCB進(jìn)程的身份證操作系統(tǒng)通過(guò)一個(gè)稱為進(jìn)程控制塊Process Control BlockPCB的數(shù)據(jù)結(jié)構(gòu)來(lái)管理和跟蹤進(jìn)程。在Linux中這個(gè)結(jié)構(gòu)體叫做task_struct它包含了操作系統(tǒng)管理進(jìn)程所需的所有信息。2.1 task_struct的主要內(nèi)容Linux內(nèi)核中的task_struct結(jié)構(gòu)體非常龐大包含數(shù)百個(gè)字段但我們可以將其主要內(nèi)容歸納為以下幾類(lèi)進(jìn)程標(biāo)識(shí)信息進(jìn)程IDPID唯一標(biāo)識(shí)一個(gè)進(jìn)程的數(shù)字父進(jìn)程IDPPID創(chuàng)建該進(jìn)程的父進(jìn)程ID用戶IDUID和組IDGID決定進(jìn)程的權(quán)限進(jìn)程狀態(tài)信息進(jìn)程當(dāng)前狀態(tài)運(yùn)行、就緒、阻塞等進(jìn)程優(yōu)先級(jí)和調(diào)度信息等待的事件或資源CPU上下文信息寄存器值當(dāng)進(jìn)程被切換出去時(shí)保存程序計(jì)數(shù)器PC值棧指針內(nèi)存管理信息頁(yè)表指針內(nèi)存分配情況共享內(nèi)存信息文件系統(tǒng)信息打開(kāi)的文件描述符表當(dāng)前工作目錄文件系統(tǒng)根目錄資源限制信息CPU時(shí)間限制內(nèi)存使用限制文件大小限制等2.2 查看進(jìn)程信息的常用命令在實(shí)際工作中我們經(jīng)常需要查看進(jìn)程的詳細(xì)信息。Linux提供了多個(gè)命令來(lái)查看PCB中的信息# 查看當(dāng)前終端下的進(jìn)程 ps # 查看系統(tǒng)中所有進(jìn)程的詳細(xì)信息 ps aux # 動(dòng)態(tài)查看進(jìn)程狀態(tài) top # 查看特定進(jìn)程的詳細(xì)信息以進(jìn)程ID 1234為例 cat /proc/1234/status其中/proc文件系統(tǒng)是一個(gè)虛擬文件系統(tǒng)它提供了訪問(wèn)內(nèi)核數(shù)據(jù)結(jié)構(gòu)的接口。每個(gè)進(jìn)程在/proc下都有一個(gè)以其PID命名的目錄包含了該進(jìn)程的詳細(xì)信息。3. 進(jìn)程的生命周期與狀態(tài)轉(zhuǎn)換Linux進(jìn)程在其生命周期中會(huì)經(jīng)歷多種狀態(tài)變化。理解這些狀態(tài)及其轉(zhuǎn)換條件對(duì)于進(jìn)程管理和性能調(diào)優(yōu)非常重要。3.1 進(jìn)程的基本狀態(tài)Linux進(jìn)程主要有以下幾種狀態(tài)運(yùn)行態(tài)TASK_RUNNING進(jìn)程正在CPU上執(zhí)行或準(zhǔn)備就緒等待調(diào)度可中斷睡眠態(tài)TASK_INTERRUPTIBLE進(jìn)程在等待某個(gè)條件如I/O完成可以被信號(hào)喚醒不可中斷睡眠態(tài)TASK_UNINTERRUPTIBLE進(jìn)程在等待硬件條件不會(huì)被信號(hào)喚醒停止態(tài)TASK_STOPPED進(jìn)程被信號(hào)如SIGSTOP暫停執(zhí)行僵尸態(tài)EXIT_ZOMBIE進(jìn)程已終止但其退出狀態(tài)尚未被父進(jìn)程獲取3.2 進(jìn)程狀態(tài)轉(zhuǎn)換圖新建 → 就緒 ? 運(yùn)行 → 終止 ↑ ↓ ← 等待具體轉(zhuǎn)換過(guò)程如下新建進(jìn)程剛被創(chuàng)建如通過(guò)fork系統(tǒng)調(diào)用但尚未被調(diào)度執(zhí)行就緒進(jìn)程已獲得除CPU外的所有必要資源等待調(diào)度器分配CPU時(shí)間運(yùn)行進(jìn)程正在CPU上執(zhí)行指令等待進(jìn)程因等待I/O操作、信號(hào)或其他資源而暫停執(zhí)行終止進(jìn)程完成執(zhí)行或被強(qiáng)制終止3.3 進(jìn)程狀態(tài)查看與實(shí)例分析我們可以使用ps命令查看進(jìn)程的當(dāng)前狀態(tài)ps -eo pid,state,cmd輸出中的STATE列顯示了進(jìn)程狀態(tài)常見(jiàn)代碼包括R運(yùn)行或可運(yùn)行S可中斷睡眠D不可中斷睡眠通常是等待I/OT停止?fàn)顟B(tài)Z僵尸進(jìn)程例如當(dāng)我們運(yùn)行一個(gè)需要用戶輸入的命令時(shí)# 在一個(gè)終端運(yùn)行 sleep 100 # 在另一個(gè)終端查看狀態(tài) ps aux | grep sleep可以看到sleep進(jìn)程的狀態(tài)是S可中斷睡眠因?yàn)樗诘却?jì)時(shí)器到期。4. 進(jìn)程創(chuàng)建fork()系統(tǒng)調(diào)用詳解在Linux中新進(jìn)程是通過(guò)復(fù)制現(xiàn)有進(jìn)程創(chuàng)建的。這個(gè)功能由fork()系統(tǒng)調(diào)用實(shí)現(xiàn)它是Linux進(jìn)程管理的核心機(jī)制之一。4.1 fork()的工作原理當(dāng)進(jìn)程調(diào)用fork()時(shí)內(nèi)核會(huì)為子進(jìn)程分配一個(gè)新的PID復(fù)制父進(jìn)程的PCBtask_struct復(fù)制父進(jìn)程的地址空間寫(xiě)時(shí)復(fù)制技術(shù)優(yōu)化將子進(jìn)程加入就緒隊(duì)列向父進(jìn)程返回子進(jìn)程的PID向子進(jìn)程返回0#include unistd.h #include stdio.h int main() { pid_t pid fork(); if (pid 0) { // fork失敗 perror(fork failed); return 1; } else if (pid 0) { // 子進(jìn)程代碼 printf(Child process (PID: %d)\n, getpid()); } else { // 父進(jìn)程代碼 printf(Parent process (PID: %d), Child PID: %d\n, getpid(), pid); } return 0; }4.2 寫(xiě)時(shí)復(fù)制Copy-On-Write優(yōu)化早期的Unix系統(tǒng)在fork()時(shí)會(huì)完整復(fù)制父進(jìn)程的內(nèi)存空間這在現(xiàn)代系統(tǒng)中效率很低。Linux采用了寫(xiě)時(shí)復(fù)制技術(shù)來(lái)優(yōu)化fork()時(shí)并不立即復(fù)制內(nèi)存頁(yè)而是讓父子進(jìn)程共享同一物理內(nèi)存內(nèi)核將這些共享內(nèi)存頁(yè)標(biāo)記為只讀當(dāng)任一進(jìn)程嘗試寫(xiě)入共享頁(yè)時(shí)觸發(fā)頁(yè)錯(cuò)誤內(nèi)核此時(shí)才復(fù)制該頁(yè)這種優(yōu)化顯著減少了fork()的開(kāi)銷(xiāo)特別是后面跟著exec()的情況這種情況下復(fù)制的內(nèi)存會(huì)被立即丟棄。4.3 fork()的常見(jiàn)使用模式在實(shí)際編程中fork()通常有以下幾種使用模式簡(jiǎn)單創(chuàng)建子進(jìn)程if (fork() 0) { // 子進(jìn)程代碼 exit(0); } // 父進(jìn)程代碼創(chuàng)建守護(hù)進(jìn)程pid_t pid fork(); if (pid 0) { exit(1); } else if (pid 0) { // 父進(jìn)程退出 exit(0); } // 子進(jìn)程繼續(xù)執(zhí)行成為守護(hù)進(jìn)程進(jìn)程池模式for (int i 0; i WORKER_NUM; i) { if (fork() 0) { // 工作進(jìn)程代碼 while (1) { // 處理任務(wù) } } }5. 進(jìn)程管理與監(jiān)控實(shí)戰(zhàn)作為L(zhǎng)inux系統(tǒng)管理員或開(kāi)發(fā)者掌握進(jìn)程管理和監(jiān)控的實(shí)用技能至關(guān)重要。下面介紹一些常用的工具和技巧。5.1 進(jìn)程監(jiān)控工具top/htop實(shí)時(shí)監(jiān)控系統(tǒng)進(jìn)程按CPU使用率排序在top界面按P按內(nèi)存使用排序按M查看特定用戶的進(jìn)程按u后輸入用戶名ps查看進(jìn)程快照# 查看完整格式的進(jìn)程信息 ps -ef # 查看特定進(jìn)程的詳細(xì)信息以nginx為例 ps -C nginx -o pid,user,cmd,%cpu,%mem,vsz,rss,tty,stat,start,timepidstat監(jiān)控進(jìn)程資源使用# 每2秒報(bào)告一次所有進(jìn)程的CPU使用情況 pidstat -u 2 # 監(jiān)控進(jìn)程的IO使用 pidstat -d 25.2 進(jìn)程管理命令啟動(dòng)進(jìn)程前臺(tái)運(yùn)行直接執(zhí)行命令后臺(tái)運(yùn)行在命令后加脫離終端運(yùn)行使用nohup或setsid終止進(jìn)程# 優(yōu)雅終止發(fā)送SIGTERM kill PID # 強(qiáng)制終止發(fā)送SIGKILL kill -9 PID # 按名稱終止進(jìn)程 pkill process_name調(diào)整進(jìn)程優(yōu)先級(jí)# 啟動(dòng)時(shí)設(shè)置優(yōu)先級(jí)nice值范圍-20到19越小優(yōu)先級(jí)越高 nice -n 10 command # 修改運(yùn)行中進(jìn)程的優(yōu)先級(jí) renice 5 -p PID5.3 處理僵尸進(jìn)程僵尸進(jìn)程是已經(jīng)終止但未被父進(jìn)程回收的進(jìn)程。它們不占用內(nèi)存但會(huì)占用PID資源。處理方法找到僵尸進(jìn)程ps aux | grep Z處理方法正常方法等待父進(jìn)程調(diào)用wait()回收強(qiáng)制方法終止父進(jìn)程僵尸進(jìn)程會(huì)被init進(jìn)程回收預(yù)防方法在代碼中正確處理SIGCHLD信號(hào)// 在父進(jìn)程中正確處理子進(jìn)程退出 signal(SIGCHLD, SIG_IGN); // 忽略SIGCHLD信號(hào)內(nèi)核自動(dòng)回收 // 或者 signal(SIGCHLD, reap_child); // 設(shè)置信號(hào)處理函數(shù)調(diào)用wait()6. 進(jìn)程間通信IPC機(jī)制概覽Linux提供了多種進(jìn)程間通信機(jī)制適用于不同場(chǎng)景。理解這些機(jī)制對(duì)于開(kāi)發(fā)復(fù)雜的多進(jìn)程應(yīng)用至關(guān)重要。6.1 主要IPC機(jī)制對(duì)比機(jī)制通信方式適用場(chǎng)景特點(diǎn)管道半雙工字節(jié)流父子進(jìn)程間通信簡(jiǎn)單但容量有限命名管道半雙工字節(jié)流任意進(jìn)程間通信有文件名可持久化消息隊(duì)列消息鏈表任意進(jìn)程間通信獨(dú)立于進(jìn)程存在共享內(nèi)存內(nèi)存區(qū)域共享高性能數(shù)據(jù)共享最快但需同步機(jī)制信號(hào)量計(jì)數(shù)器進(jìn)程同步協(xié)調(diào)共享資源訪問(wèn)信號(hào)軟件中斷簡(jiǎn)單事件通知異步信息量有限套接字網(wǎng)絡(luò)/本地通信網(wǎng)絡(luò)或本地進(jìn)程通信最通用跨主機(jī)6.2 常用IPC編程示例匿名管道int pipefd[2]; pipe(pipefd); // 創(chuàng)建管道 if (fork() 0) { // 子進(jìn)程寫(xiě)入管道 close(pipefd[0]); // 關(guān)閉讀端 write(pipefd[1], hello, 6); exit(0); } else { // 父進(jìn)程從管道讀取 close(pipefd[1]); // 關(guān)閉寫(xiě)端 char buf[10]; read(pipefd[0], buf, sizeof(buf)); printf(Received: %s\n, buf); }共享內(nèi)存// 創(chuàng)建共享內(nèi)存段 int shmid shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666); int *counter (int*)shmat(shmid, NULL, 0); if (fork() 0) { // 子進(jìn)程遞增計(jì)數(shù)器 (*counter); shmdt(counter); } else { // 父進(jìn)程等待并讀取 wait(NULL); printf(Counter value: %d\n, *counter); shmdt(counter); shmctl(shmid, IPC_RMID, NULL); // 刪除共享內(nèi)存 }7. 進(jìn)程與線程的關(guān)系與區(qū)別在現(xiàn)代操作系統(tǒng)中線程Thread是比進(jìn)程更輕量級(jí)的執(zhí)行單元。理解它們的關(guān)系對(duì)編寫(xiě)高效并發(fā)程序很重要。7.1 關(guān)鍵區(qū)別對(duì)比特性進(jìn)程線程創(chuàng)建開(kāi)銷(xiāo)大需要復(fù)制PCB和地址空間小共享地址空間通信方式IPC管道、共享內(nèi)存等直接讀寫(xiě)進(jìn)程內(nèi)存上下文切換開(kāi)銷(xiāo)大開(kāi)銷(xiāo)小獨(dú)立性有獨(dú)立地址空間互不影響共享地址空間一個(gè)線程崩潰可能影響整個(gè)進(jìn)程資源分配操作系統(tǒng)分配由進(jìn)程管理安全性高隔離性好低共享數(shù)據(jù)需同步7.2 Linux中的線程實(shí)現(xiàn)Linux使用一種獨(dú)特的線程實(shí)現(xiàn)方式輕量級(jí)進(jìn)程LWPLinux內(nèi)核并不區(qū)分進(jìn)程和線程線程被視為共享某些資源的進(jìn)程clone()系統(tǒng)調(diào)用比f(wàn)ork()更靈活可以控制哪些資源被共享POSIX線程庫(kù)pthread用戶空間的線程API底層使用clone()#include pthread.h void* thread_func(void* arg) { printf(Thread running\n); return NULL; } int main() { pthread_t tid; pthread_create(tid, NULL, thread_func, NULL); pthread_join(tid, NULL); return 0; }7.3 選擇進(jìn)程還是線程在實(shí)際開(kāi)發(fā)中應(yīng)根據(jù)需求選擇合適的并發(fā)模型使用進(jìn)程的場(chǎng)景需要高安全性和隔離性應(yīng)用由獨(dú)立組件構(gòu)成需要利用多機(jī)分布式處理使用線程的場(chǎng)景需要高性能和低開(kāi)銷(xiāo)任務(wù)間需要頻繁通信和數(shù)據(jù)共享程序是計(jì)算密集型的特別是多核CPU8. Linux進(jìn)程調(diào)度策略解析Linux內(nèi)核的進(jìn)程調(diào)度器負(fù)責(zé)決定哪個(gè)進(jìn)程可以獲得CPU時(shí)間。理解調(diào)度策略有助于優(yōu)化程序性能。8.1 主要調(diào)度策略完全公平調(diào)度器CFS默認(rèn)策略基于虛擬運(yùn)行時(shí)間分配CPU實(shí)時(shí)調(diào)度策略SCHED_FIFO先進(jìn)先出高優(yōu)先級(jí)進(jìn)程會(huì)一直運(yùn)行直到主動(dòng)放棄CPUSCHED_RR輪轉(zhuǎn)調(diào)度同優(yōu)先級(jí)進(jìn)程按時(shí)間片輪轉(zhuǎn)批處理調(diào)度SCHED_BATCH適用于非交互式、CPU密集型任務(wù)空閑調(diào)度SCHED_IDLE只在系統(tǒng)空閑時(shí)運(yùn)行8.2 調(diào)度優(yōu)先級(jí)普通進(jìn)程使用動(dòng)態(tài)優(yōu)先級(jí)nice值從-20到19默認(rèn)0實(shí)時(shí)進(jìn)程靜態(tài)優(yōu)先級(jí)1到99數(shù)字越大優(yōu)先級(jí)越高查看和修改進(jìn)程優(yōu)先級(jí)# 查看進(jìn)程優(yōu)先級(jí) ps -eo pid,ni,pri,cmd # 啟動(dòng)時(shí)設(shè)置nice值 nice -n 10 ./program # 修改運(yùn)行中進(jìn)程的nice值 renice 5 -p PID8.3 調(diào)度策略設(shè)置示例#include sched.h struct sched_param param; param.sched_priority 50; // 實(shí)時(shí)優(yōu)先級(jí) // 設(shè)置為實(shí)時(shí)輪轉(zhuǎn)調(diào)度策略 if (sched_setscheduler(0, SCHED_RR, param) -1) { perror(sched_setscheduler failed); exit(1); }注意錯(cuò)誤使用實(shí)時(shí)調(diào)度策略可能導(dǎo)致系統(tǒng)不穩(wěn)定普通應(yīng)用程序通常不需要修改調(diào)度策略。9. 特殊進(jìn)程類(lèi)型解析Linux系統(tǒng)中有幾種特殊的進(jìn)程類(lèi)型它們?cè)谙到y(tǒng)運(yùn)行中扮演著重要角色。9.1 init進(jìn)程init進(jìn)程是系統(tǒng)啟動(dòng)后創(chuàng)建的第一個(gè)用戶空間進(jìn)程PID為1負(fù)責(zé)啟動(dòng)系統(tǒng)服務(wù)回收孤兒進(jìn)程維護(hù)運(yùn)行級(jí)別作為所有進(jìn)程的祖先進(jìn)程在現(xiàn)代Linux系統(tǒng)中init進(jìn)程通常被systemd取代# 查看init進(jìn)程信息 ps -p 1 -o pid,cmd9.2 守護(hù)進(jìn)程Daemon守護(hù)進(jìn)程是在后臺(tái)運(yùn)行的特殊進(jìn)程特點(diǎn)包括脫離控制終端通常以root權(quán)限運(yùn)行生命周期長(zhǎng)通常處理系統(tǒng)級(jí)任務(wù)創(chuàng)建守護(hù)進(jìn)程的典型步驟pid_t pid fork(); if (pid 0) exit(1); if (pid 0) exit(0); // 父進(jìn)程退出 setsid(); // 創(chuàng)建新會(huì)話 // 處理文件描述符、工作目錄等 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); chdir(/); // 守護(hù)進(jìn)程主循環(huán) while (1) { // 執(zhí)行任務(wù) sleep(1); }9.3 孤兒進(jìn)程與僵尸進(jìn)程孤兒進(jìn)程父進(jìn)程先于子進(jìn)程退出子進(jìn)程被init進(jìn)程收養(yǎng)僵尸進(jìn)程子進(jìn)程退出但父進(jìn)程未調(diào)用wait()獲取其退出狀態(tài)處理僵尸進(jìn)程的正確方法// 設(shè)置SIGCHLD處理函數(shù) void sigchld_handler(int sig) { while (waitpid(-1, NULL, WNOHANG) 0); } // 注冊(cè)信號(hào)處理 struct sigaction sa; sa.sa_handler sigchld_handler; sigemptyset(sa.sa_mask); sa.sa_flags SA_RESTART | SA_NOCLDSTOP; sigaction(SIGCHLD, sa, NULL);10. 進(jìn)程性能分析與優(yōu)化在實(shí)際生產(chǎn)環(huán)境中進(jìn)程性能分析和優(yōu)化是系統(tǒng)管理員和開(kāi)發(fā)者的重要工作。10.1 性能分析工具strace跟蹤系統(tǒng)調(diào)用和信號(hào)strace -c -p PID # 統(tǒng)計(jì)系統(tǒng)調(diào)用 strace -T -p PID # 顯示調(diào)用耗時(shí)ltrace跟蹤庫(kù)函數(shù)調(diào)用ltrace -c ./programperf強(qiáng)大的性能分析工具perf top # 實(shí)時(shí)查看熱點(diǎn)函數(shù) perf stat ./program # 統(tǒng)計(jì)程序運(yùn)行指標(biāo) perf record -g ./program # 記錄性能數(shù)據(jù) perf report # 分析記錄的數(shù)據(jù)gdb調(diào)試運(yùn)行中的進(jìn)程gdb -p PID10.2 常見(jiàn)性能問(wèn)題與優(yōu)化CPU瓶頸優(yōu)化熱點(diǎn)函數(shù)通過(guò)perf定位減少鎖競(jìng)爭(zhēng)使用更高效的算法內(nèi)存問(wèn)題減少內(nèi)存分配/釋放頻率避免內(nèi)存泄漏使用valgrind檢測(cè)優(yōu)化數(shù)據(jù)結(jié)構(gòu)和緩存使用I/O問(wèn)題使用異步I/O合并小I/O操作調(diào)整I/O調(diào)度策略上下文切換過(guò)多減少不必要的進(jìn)程/線程數(shù)量使用線程池模式調(diào)整進(jìn)程親和性taskset# 將進(jìn)程綁定到特定CPU核心 taskset -c 0,1 ./program10.3 進(jìn)程資源限制Linux提供了對(duì)進(jìn)程資源使用的限制機(jī)制# 查看當(dāng)前限制 ulimit -a # 設(shè)置限制如最大打開(kāi)文件數(shù) ulimit -n 10240 # 通過(guò)cgroups更精細(xì)的控制 cgcreate -g cpu,memory:/mygroup cgset -r cpu.shares512 /mygroup cgexec -g cpu,memory:/mygroup ./program在實(shí)際工作中我發(fā)現(xiàn)很多性能問(wèn)題源于對(duì)進(jìn)程行為的誤解。例如一個(gè)常見(jiàn)的誤區(qū)是認(rèn)為更多的進(jìn)程/線程總會(huì)帶來(lái)更好的性能。實(shí)際上過(guò)多的并發(fā)會(huì)導(dǎo)致大量的上下文切換開(kāi)銷(xiāo)反而降低整體性能。正確的做法是根據(jù)硬件資源特別是CPU核心數(shù)和工作負(fù)載特性來(lái)調(diào)整并發(fā)度。