欧美成人午夜精品久久久,国产?V天堂一区二区三区,欧美精品va在线观看,亚洲一区二区三区免费在线观看,av无码精品一区二区久久,欧美性爱视频不卡一区三区,欧美乱人伦视频在线观看,国产一级牲交高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

Linux fork函數(shù)詳解:返回值、COW寫(xiě)時(shí)復(fù)制與僵尸進(jìn)程排查

Linux fork函數(shù)詳解:返回值、COW寫(xiě)時(shí)復(fù)制與僵尸進(jìn)程排查 第一次看到fork這個(gè)函數(shù)我盯著那句“調(diào)用一次返回兩次”琢磨了挺久——一個(gè)函數(shù)怎么可能有兩次返回后來(lái)在內(nèi)核源碼里把kernel_clone到copy_process這條路走了一遍才算真正把這件事想通。它難懂不是因?yàn)楦拍钣卸嘈醵且驗(yàn)樗荒_踩在用戶態(tài) API 和內(nèi)核調(diào)度器的交界處你在 C 代碼里看到的只是一行函數(shù)調(diào)用背后卻是整個(gè)進(jìn)程地址空間的復(fù)制、頁(yè)表的重新登記、調(diào)度實(shí)體的插入。Linux 的 fork 函數(shù)幾乎是所有多進(jìn)程程序的起點(diǎn)從 shell 執(zhí)行命令、Nginx 拉起 worker、到你自己寫(xiě)的批量任務(wù)分發(fā)腳本底層都是同一套東西。這篇文章我想寫(xiě)給兩類人一類是剛學(xué)完操作系統(tǒng)課本、知道“fork 會(huì)復(fù)制進(jìn)程”但一寫(xiě)代碼就蒙的同學(xué)另一類是在項(xiàng)目里被僵尸進(jìn)程、緩沖區(qū)重復(fù)輸出、子進(jìn)程不受控這些問(wèn)題咬過(guò)、想把這套機(jī)制徹底捋順的開(kāi)發(fā)者。我會(huì)從內(nèi)核實(shí)現(xiàn)路徑、返回值語(yǔ)義、代碼實(shí)操、參數(shù)取舍一路講到排查實(shí)錄代碼都能直接跑坑也都標(biāo)出來(lái)。1. fork 的本質(zhì)一次調(diào)用為何有兩次返回1.1 從用戶態(tài)看它只是三個(gè)整數(shù)之一從調(diào)用者角度看fork的接口簡(jiǎn)單到幾乎沒(méi)有任何可配置項(xiàng)——沒(méi)有參數(shù)沒(méi)有任何 flag只返回一個(gè)pid_t。這個(gè)返回值分三種情況必須先記牢因?yàn)楹竺?90% 的 bug 都源于這里判斷錯(cuò)了返回值出現(xiàn)在哪個(gè)進(jìn)程含義 0父進(jìn)程這個(gè)值是剛創(chuàng)建出來(lái)的子進(jìn)程 PID 0子進(jìn)程說(shuō)明“我就是那個(gè)新進(jìn)程”沒(méi)有別的信息 -1父進(jìn)程創(chuàng)建失敗原因看errno有一點(diǎn)很容易被忽略子進(jìn)程拿到的 0 不是“子進(jìn)程的 PID 是 0”而是一個(gè)標(biāo)記位。子進(jìn)程想知道自己的 PID 得調(diào)getpid()想知道爹是誰(shuí)得調(diào)getppid()。我見(jiàn)過(guò)不少人寫(xiě)成if (pid 0) { /* 子進(jìn)程 */ }邏輯反了還不報(bào)錯(cuò)程序在多核機(jī)器上跑出來(lái)的結(jié)果飄忽不定排查半天才發(fā)現(xiàn)是分支寫(xiě)反。#include stdio.h #include unistd.h #include sys/types.h int main(void) { pid_t pid fork(); if (pid 0) { perror(fork); return 1; } else if (pid 0) { printf(child : pid%d ppid%d\n, getpid(), getppid()); } else { printf(parent: pid%d child%d\n, getpid(), pid); } return 0; }編譯就用gcc -Wall -O0 fork_demo.c -o fork_demo加-Wall是習(xí)慣編譯器對(duì)fork相關(guān)的返回值未檢查會(huì)給出提示能擋掉一批低級(jí)錯(cuò)誤。1.2 內(nèi)核里那條路從系統(tǒng)調(diào)用到copy_process用戶態(tài)的一次fork()最終會(huì)落到內(nèi)核的sys_forkx86-64 上走_(dá)_x64_sys_fork再進(jìn)到kernel_clone。這個(gè)名字在不同內(nèi)核版本里變過(guò)老版本叫_do_fork5.x 之后統(tǒng)一成kernel_clone。真正干重活的是copy_process它按順序做了這么幾件事dup_task_struct復(fù)制一份task_struct和內(nèi)核棧此時(shí)父子進(jìn)程的描述符已經(jīng)存在但內(nèi)容還很“空”。一系列權(quán)限與配額檢查RLIMIT_NPROC限制、系統(tǒng)級(jí)線程數(shù)上限、用戶進(jìn)程數(shù)上限任何一項(xiàng)超了就直接返回錯(cuò)誤。sched_fork給新任務(wù)初始化調(diào)度實(shí)體把它掛到調(diào)度器上但此時(shí)還沒(méi)真正運(yùn)行。copy_files、copy_fs、copy_sighand這幾項(xiàng)大多是增加引用計(jì)數(shù)而不是深拷貝。打開(kāi)的文件表、信號(hào)處理函數(shù)表、工作目錄這些父子共享同一份內(nèi)核對(duì)象。copy_mm這是最重的一步復(fù)制內(nèi)存描述符、遍歷所有 VMA、復(fù)制頁(yè)表并把父子雙方的頁(yè)表項(xiàng)統(tǒng)統(tǒng)改成只讀。alloc_pid分配一個(gè)新的 PID。wake_up_new_task把子進(jìn)程放進(jìn)運(yùn)行隊(duì)列等調(diào)度器挑中它。父進(jìn)程在kernel_clone返回處拿到子進(jìn)程 PID子進(jìn)程不是“返回”到這個(gè)位置而是被調(diào)度到時(shí)從ret_from_fork這條棧幀直接跳回用戶態(tài)返回值寄存器被填成 0。所以“一次調(diào)用兩次返回”這個(gè)說(shuō)法其實(shí)有點(diǎn)誤導(dǎo)——它不是同一個(gè)函數(shù)返了兩遍而是兩個(gè)獨(dú)立的執(zhí)行流各自從內(nèi)核態(tài)穿越回用戶態(tài)只是它們穿越前在同一段內(nèi)核代碼里待過(guò)。1.3 為什么不做全量拷貝COW 的取舍邏輯如果fork真的把父進(jìn)程幾百 MB 內(nèi)存整塊復(fù)制一遍那創(chuàng)建一個(gè)進(jìn)程的開(kāi)銷會(huì)大到?jīng)]法用。早期的確是這個(gè)思路fork后緊跟execve的場(chǎng)景浪費(fèi)極其嚴(yán)重——復(fù)制了一大堆馬上要被覆蓋的內(nèi)存。寫(xiě)時(shí)復(fù)制Copy-On-Write簡(jiǎn)稱 COW就是為了解決這個(gè)浪費(fèi)copy_mm復(fù)制頁(yè)表時(shí)父子進(jìn)程的頁(yè)表項(xiàng)指向同一批物理頁(yè)只是把這些頁(yè)的權(quán)限位從可寫(xiě)改成只讀同時(shí)在task_struct里把頁(yè)標(biāo)記成 COW 頁(yè)。真正的復(fù)制推遲到有人寫(xiě)的那一刻。任意一方寫(xiě)入觸發(fā)缺頁(yè)異常內(nèi)核發(fā)現(xiàn)這是個(gè) COW 頁(yè)才分配新物理頁(yè)、把原內(nèi)容拷過(guò)去、改回可寫(xiě)然后重新執(zhí)行那條指令。這個(gè)設(shè)計(jì)的精妙之處在于只讀的父子進(jìn)程幾乎零成本只有真正被修改過(guò)的頁(yè)才付出復(fù)制代價(jià)。但 COW 不是沒(méi)有成本。fork的耗時(shí)和進(jìn)程當(dāng)前占用的虛擬內(nèi)存成正比因?yàn)轫?yè)表本身要復(fù)制。粗算一下x86-64 上普通頁(yè)是 4KB一個(gè)占 1GB 內(nèi)存的進(jìn)程大約有 26 萬(wàn)個(gè)頁(yè)表項(xiàng)每個(gè) PTE 8 字節(jié)光頁(yè)表數(shù)據(jù)就是 2MB 左右再加上遍歷 VMA 的時(shí)間。所以你會(huì)發(fā)現(xiàn)一個(gè)現(xiàn)象——空進(jìn)程fork微秒級(jí)就完了幾百 MB 的服務(wù)進(jìn)程fork一次可能要好幾個(gè)毫秒。這個(gè)結(jié)論直接影響了后面的選型判斷。注意COW 讓父子共享物理頁(yè)但邏輯上是兩個(gè)獨(dú)立的地址空間。子進(jìn)程里的malloc返回值在父進(jìn)程里沒(méi)有任何意義別指望用這個(gè)地址跨進(jìn)程傳數(shù)據(jù)那需要共享內(nèi)存或者管道。2. 執(zhí)行流、競(jìng)爭(zhēng)與繼承那些課本上不講清楚的事2.1 父子誰(shuí)先跑答案是“不知道”fork返回之后父進(jìn)程和子進(jìn)程誰(shuí)先被 CPU 執(zhí)行完全由調(diào)度器決定沒(méi)有任何順序保證。在多核機(jī)器上兩個(gè)進(jìn)程大概率是真并行在單核上時(shí)間片怎么分也看調(diào)度策略。這意味著任何依賴“父進(jìn)程先執(zhí)行完再輪到子進(jìn)程”的代碼都是錯(cuò)的。我踩過(guò)的第一個(gè)坑就出在這里一個(gè)父進(jìn)程里 fork 之后立刻往共享的文件描述符寫(xiě)數(shù)據(jù)子進(jìn)程也寫(xiě)結(jié)果兩次實(shí)驗(yàn)跑出來(lái)的內(nèi)容順序完全不一樣。當(dāng)時(shí)以為是文件系統(tǒng)的問(wèn)題其實(shí)是執(zhí)行順序不確定。正確的處理方式是顯式同步——用waitpid等子進(jìn)程結(jié)束用管道通信用信號(hào)量互斥而不是靠“大概會(huì)先跑我”。#include stdio.h #include unistd.h #include sys/wait.h int main(void) { pid_t pid fork(); if (pid 0) { printf(child working\n); _exit(0); } int status 0; waitpid(pid, status, 0); printf(child exited, status%d\n, WEXITSTATUS(status)); return 0; }子進(jìn)程退出用_exit而不是exit這是個(gè)細(xì)節(jié)但很重要。exit會(huì)執(zhí)行atexit注冊(cè)的函數(shù)、刷新 stdio 緩沖區(qū)而這些緩沖區(qū)是從父進(jìn)程繼承來(lái)的如果父進(jìn)程 fork 前有沒(méi)刷新的內(nèi)容子進(jìn)程exit時(shí)又刷一遍輸出就重復(fù)了。_exit直接走系統(tǒng)調(diào)用跳過(guò)所有這些用戶態(tài)清理干凈利落。2.2 文件描述符繼承共享的不只是“編號(hào)”fork之后子進(jìn)程會(huì)得到父進(jìn)程所有打開(kāi)文件描述符的副本但這里有個(gè)特別容易誤解的地方復(fù)制的是描述符不是文件對(duì)象。父子雙方各自的 fd 編號(hào)可能不同但它們指向同一個(gè)struct file而struct file里存著文件偏移量。后果很直觀父進(jìn)程讀了 100 字節(jié)子進(jìn)程接著讀會(huì)從第 101 字節(jié)開(kāi)始而不是從頭讀。寫(xiě)文件同理兩邊交替寫(xiě)會(huì)互相覆蓋偏移。我在做一個(gè)日志切分的小工具時(shí)就被這個(gè)咬過(guò)父子都往同一個(gè)日志文件追加結(jié)果日志里出現(xiàn)了大片空洞——因?yàn)閮蛇叾荚谟胠seek挪同一個(gè)偏移量。想避免這個(gè)問(wèn)題常規(guī)做法是父子需要獨(dú)立讀寫(xiě)位置時(shí)子進(jìn)程 fork 之后自己重新open一次文件或者應(yīng)用層用O_APPEND打開(kāi)讓每次寫(xiě)都由內(nèi)核原子地定位到文件末尾或者干脆別讓多個(gè)進(jìn)程寫(xiě)同一個(gè)文件改成各自寫(xiě)各自的后續(xù)再合并。除了文件描述符子進(jìn)程還會(huì)繼承當(dāng)前工作目錄、信號(hào)處理方式SIG_IGN和自定義處理函數(shù)都繼承但未處理的信號(hào)會(huì)重置為默認(rèn)、umask、環(huán)境變量、資源限制。這些在寫(xiě)守護(hù)進(jìn)程的時(shí)候會(huì)集中爆發(fā)問(wèn)題。2.3 多線程進(jìn)程里 fork 的隱藏雷區(qū)這是我認(rèn)為最需要單獨(dú)拎出來(lái)說(shuō)的一條。fork只會(huì)復(fù)制調(diào)用它的那個(gè)線程其他線程在子進(jìn)程里全都不存在。但問(wèn)題來(lái)了那些線程持有的互斥鎖、條件變量、讀寫(xiě)鎖狀態(tài)是被原樣復(fù)制過(guò)去的。如果 fork 的瞬間某個(gè)鎖正被另一個(gè)線程持有那么在子進(jìn)程里這把鎖永遠(yuǎn)處于“被鎖住”的狀態(tài)而持有者已經(jīng)不存在了任何試圖加鎖的代碼都會(huì)永久阻塞。規(guī)避方式有三條路按推薦程度排fork 完立刻 execve。這是最安全的姿勢(shì)execve會(huì)把整個(gè)用戶態(tài)地址空間換掉鎖的狀態(tài)也一并消失。絕大多數(shù)“fork 后要干事”的場(chǎng)景其實(shí)都該走這條路。fork 之前保證沒(méi)有其他線程在跑比如在程序啟動(dòng)早期就把需要 fork 的邏輯做完。用pthread_atfork注冊(cè) prepare/parent/child 三個(gè)鉤子在 fork 前后手動(dòng)加解鎖。這套機(jī)制能解決問(wèn)題但很容易寫(xiě)成死鎖尤其是涉及多把鎖的時(shí)候加鎖順序稍不注意就翻車(chē)。提示如果你的程序用了線程池同時(shí)又有 fork 子進(jìn)程的需求請(qǐng)優(yōu)先考慮把子進(jìn)程部分改成獨(dú)立進(jìn)程或者獨(dú)立的服務(wù)不要在同一進(jìn)程里混用?;煊脦?lái)的調(diào)試成本遠(yuǎn)高于拆開(kāi)的改造成本。3. 動(dòng)手實(shí)操?gòu)淖钚?Demo 到可用的進(jìn)程管理3.1 循環(huán) fork 的 2 的 n 次方陷阱先看一段看起來(lái)人畜無(wú)害的代碼for (int i 0; i 3; i) { fork(); printf(pid%d, i%d\n, getpid(), i); }很多人以為這會(huì)產(chǎn)生 3 個(gè)子進(jìn)程加 1 個(gè)父進(jìn)程。實(shí)際結(jié)果是 8 個(gè)進(jìn)程。原因在于fork之后父進(jìn)程繼續(xù)循環(huán)子進(jìn)程也從 fork 的下一行繼續(xù)執(zhí)行于是它也進(jìn)入下一輪循環(huán)并且再次 fork。每一輪都把當(dāng)前進(jìn)程數(shù)翻倍3 輪就是 23 8。這個(gè)行為本身沒(méi)錯(cuò)是很多人對(duì)“子進(jìn)程從哪開(kāi)始執(zhí)行”的理解有偏差。子進(jìn)程不是從main重頭開(kāi)始而是從fork返回點(diǎn)繼續(xù)。如果確實(shí)需要?jiǎng)?chuàng)建 N 個(gè)并列的工作進(jìn)程比如預(yù)派生模型正確寫(xiě)法是在子進(jìn)程里立刻跳出循環(huán)#define WORKERS 4 for (int i 0; i WORKERS; i) { pid_t pid fork(); if (pid 0) { perror(fork); break; } if (pid 0) { worker_loop(i); /* 子進(jìn)程干活不再進(jìn)入下一輪 */ _exit(0); } } /* 父進(jìn)程在這里統(tǒng)一 wait */關(guān)鍵就是if (pid 0)分支里干完活直接_exit絕不落回循環(huán)體。這個(gè)模式叫預(yù)派生pre-forkNginx 的 worker 模型、老式 Apache 的 prefork 都是這個(gè)思路。好處是每個(gè) worker 獨(dú)立壞處是 worker 數(shù)在啟動(dòng)時(shí)就固定了得配合平滑重啟來(lái)調(diào)整。3.2 用 fork execve 寫(xiě)一個(gè)迷你 shell想真正理解 fork最好的練習(xí)是寫(xiě)一個(gè)能跑命令的 shell。它的核心邏輯只有四步讀一行、切參數(shù)、fork、子進(jìn)程 exec。#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/wait.h #define MAXLINE 1024 int main(void) { char line[MAXLINE]; while (fgets(line, sizeof(line), stdin) ! NULL) { line[strcspn(line, \n)] \0; if (line[0] \0) continue; if (strcmp(line, exit) 0) break; char *argv[64]; int argc 0; char *tok strtok(line, ); while (tok ! NULL argc 63) { argv[argc] tok; tok strtok(NULL, ); } argv[argc] NULL; pid_t pid fork(); if (pid 0) { perror(fork); continue; } if (pid 0) { execvp(argv[0], argv); perror(execvp); /* 只有 exec 失敗才會(huì)走到這里 */ _exit(127); } int status 0; waitpid(pid, status, 0); if (WIFEXITED(status)) { printf([exit %d]\n, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf([killed by signal %d]\n, WTERMSIG(status)); } } return 0; }幾個(gè)值得說(shuō)的點(diǎn)。execvp會(huì)自己去PATH里找可執(zhí)行文件所以直接敲ls就能跑。execvp成功的話永遠(yuǎn)不會(huì)返回返回值只在失敗時(shí)有用失敗后必須_exit(127)用 127 是 shell 界的慣例表示“命令沒(méi)找到”。waitpid拿到的status是個(gè)打包值不能直接當(dāng)退出碼用得用WIFEXITED、WEXITSTATUS、WIFSIGNALED這些宏去拆。我第一次寫(xiě)的時(shí)候直接printf(%d, status)輸出 256 讓我困惑了很久——其實(shí)真實(shí)退出碼是 1因?yàn)橥顺龃a存在高 8 位。這個(gè) shell 還很粗糙不支持管道、重定向、后臺(tái)任務(wù)但骨架已經(jīng)對(duì)了。想支持管道就需要在 fork 之前先pipe()然后兩個(gè)子進(jìn)程分別把dup2把讀端寫(xiě)端接到標(biāo)準(zhǔn)輸入輸出上這是個(gè)很好的練手項(xiàng)目。3.3 并行任務(wù)分發(fā)怎么定并發(fā)數(shù)再給一個(gè)更貼近實(shí)際工作的例子——把一批耗時(shí)任務(wù)拆給多個(gè)子進(jìn)程并行跑。這個(gè)模式在數(shù)據(jù)預(yù)處理、批量轉(zhuǎn)碼、壓測(cè)腳本里特別常見(jiàn)。#include stdio.h #include unistd.h #include sys/wait.h #define JOBS 4 static void do_work(int id) { sleep(1); /* 模擬耗時(shí)計(jì)算 */ printf(job %d done by pid %d\n, id, getpid()); } int main(void) { pid_t pids[JOBS]; for (int i 0; i JOBS; i) { pid_t pid fork(); if (pid 0) { perror(fork); pids[i] -1; continue; } if (pid 0) { do_work(i); _exit(0); } pids[i] pid; } for (int i 0; i JOBS; i) { if (pids[i] 0) { int status 0; waitpid(pids[i], status, 0); printf(child %d reaped, status%d\n, pids[i], WEXITSTATUS(status)); } } return 0; }并發(fā)數(shù)怎么定我的經(jīng)驗(yàn)是別超過(guò) CPU 邏輯核數(shù)。純計(jì)算型任務(wù)進(jìn)程數(shù)等于核數(shù)時(shí)吞吐最高再多只會(huì)增加上下文切換和內(nèi)存壓力??梢杂胹ysconf(_SC_NPROCESSORS_ONLN)拿到當(dāng)前可用核數(shù)再乘一個(gè)系數(shù)I/O 密集型任務(wù)等待磁盤(pán)、網(wǎng)絡(luò)系數(shù)取 2 到 4CPU 密集型任務(wù)系數(shù)取 1每個(gè)子進(jìn)程內(nèi)存占用大比如幾百 MB還得反過(guò)來(lái)壓低數(shù)量防止觸發(fā) OOM。另外要注意waitpid的回收順序。上面這段代碼是按創(chuàng)建順序回收的如果第 0 個(gè)任務(wù)特別慢后面三個(gè)早就跑完了也得等著。想做到“誰(shuí)先完誰(shuí)先回收”用waitpid(-1, status, 0)循環(huán)回收任意子進(jìn)程或者干脆用SIGCHLD信號(hào)處理。4. 資源、參數(shù)與選型什么時(shí)候該用 fork什么時(shí)候不該4.1 fork 失敗的兩種典型 errnofork返回 -1 時(shí)errno最常見(jiàn)的兩個(gè)值是EAGAIN和ENOMEM含義完全不同排查方向也不一樣。EAGAIN表示“資源暫時(shí)不夠”通常是進(jìn)程數(shù)配額打滿了。要檢查幾個(gè)地方RLIMIT_NPROC用ulimit -u看、系統(tǒng)級(jí)kernel.pid_max、kernel.threads-max還有 cgroup 里的pids.max。在容器環(huán)境里跑最容易撞的是 cgroup 的 pids 限制從宿主機(jī)上看一切正常容器里怎么都 fork 不出來(lái)。我遇到過(guò)的一次就是容器 pids 上限設(shè)得太小業(yè)務(wù)里但凡有個(gè) fork 都失敗日志里只留一行“Resource temporarily unavailable”查了半天才定位到配額。ENOMEM則是內(nèi)存不夠。注意這不一定是物理內(nèi)存耗盡也可能是因?yàn)?COW 機(jī)制下內(nèi)核需要為新進(jìn)程分配task_struct和內(nèi)核棧同時(shí)在復(fù)制頁(yè)表時(shí)需要申請(qǐng)內(nèi)存。內(nèi)存緊張時(shí)一個(gè)本身不大的進(jìn)程 fork 也可能失敗。這時(shí)候該看的是dmesg里有沒(méi)有 OOM 相關(guān)記錄以及/proc/meminfo的CommitLimit和Committed_AS。堆棧上還有一個(gè)坑內(nèi)核棧默認(rèn)不大歷史上是 8KB某些配置下更小fork本身不占用戶棧但如果你的代碼在fork前遞歸很深子進(jìn)程復(fù)制的是整個(gè)地址空間的映射雖然 COW 不會(huì)立刻復(fù)制物理頁(yè)但虛擬地址空間的布局是完全一致的棧溢出風(fēng)險(xiǎn)同樣被繼承過(guò)去。4.2 fork、vfork、clone、posix_spawn 怎么選這四個(gè)東西經(jīng)常被放在一起比較但它們的定位差別很大接口地址空間典型用途注意事項(xiàng)fork完全復(fù)制COW通用進(jìn)程創(chuàng)建大內(nèi)存進(jìn)程下耗時(shí)隨內(nèi)存增長(zhǎng)vfork與父進(jìn)程共享父進(jìn)程阻塞fork 后立刻 exec 的老場(chǎng)景子進(jìn)程不能 return只能_exit或 execclone可精細(xì)控制共享哪些資源實(shí)現(xiàn)線程、命名空間隔離參數(shù)復(fù)雜直接用的場(chǎng)景不多posix_spawn內(nèi)部實(shí)現(xiàn)可能用 vfork/clone單純想“起個(gè)程序”接口受限不適合 fork 后跑自定義邏輯選型上的判斷其實(shí)很簡(jiǎn)單如果你 fork 之后馬上就要 execve那就用posix_spawn它在 glibc 里會(huì)走clone(CLONE_VM | CLONE_VFORK)省掉整個(gè)頁(yè)表復(fù)制的開(kāi)銷在大內(nèi)存進(jìn)程里差距非常明顯。我在一個(gè)占內(nèi)存接近 1GB 的服務(wù)里把fork exec換成posix_spawn創(chuàng)建子進(jìn)程的耗時(shí)從毫秒級(jí)降到了幾十微秒級(jí)效果立竿見(jiàn)影。如果 fork 之后子進(jìn)程要跑一段自己的 C 邏輯改環(huán)境、設(shè)權(quán)限、接著算那還是老老實(shí)實(shí)fork。vfork不要碰它的約束太苛刻稍微寫(xiě)錯(cuò)一點(diǎn)就是未定義行為而且現(xiàn)代 glibc 的fork已經(jīng)在很多場(chǎng)景下優(yōu)化得夠好了。如果你需要的是“共享地址空間的并發(fā)”那你其實(shí)想要的是線程應(yīng)該用pthread_create而不是clone。clone是給需要做命名空間隔離、實(shí)現(xiàn)容器運(yùn)行時(shí)這類底層工具準(zhǔn)備的。4.3 內(nèi)存開(kāi)銷的實(shí)測(cè)感受我自己做過(guò)一個(gè)粗略的對(duì)比測(cè)試在同一臺(tái)機(jī)器上讓一個(gè)進(jìn)程分別占用 10MB、100MB、500MB 匿名內(nèi)存然后各 fork 1000 次記錄平均耗時(shí)。數(shù)量級(jí)上的結(jié)論是10MB 時(shí) fork 大約在幾十微秒100MB 時(shí)漲到一兩百微秒500MB 時(shí)到了毫秒級(jí)。這個(gè)增長(zhǎng)主要來(lái)自頁(yè)表復(fù)制和 VMA 遍歷跟寫(xiě)入多少數(shù)據(jù)無(wú)關(guān)。這個(gè)結(jié)論有很實(shí)際的指導(dǎo)意義如果你的服務(wù)常駐內(nèi)存很大就不要在熱路徑上頻繁 fork。要么改成常駐的 worker 池啟動(dòng)時(shí)一次性 fork 好之后靠任務(wù)隊(duì)列分發(fā)要么改用線程池要么在 fork 前盡量減少不必要的內(nèi)存映射。反之如果進(jìn)程很小比如一個(gè)命令行小工具fork 的開(kāi)銷基本可以忽略不用過(guò)度設(shè)計(jì)。5. 常見(jiàn)問(wèn)題與排查實(shí)錄5.1 僵尸進(jìn)程不是“沒(méi)死透”是“沒(méi)人收尸”子進(jìn)程結(jié)束后內(nèi)核不會(huì)立刻把它的task_struct全部釋放因?yàn)楦高M(jìn)程可能還需要讀取退出狀態(tài)。這個(gè)狀態(tài)叫僵尸態(tài)Z。只要父進(jìn)程調(diào)用了wait或waitpid狀態(tài)被讀取資源才會(huì)真正回收。如果父進(jìn)程一直不回收僵尸會(huì)越積越多。單個(gè)僵尸占的內(nèi)存不多主要是一個(gè)task_struct加內(nèi)核棧但 PID 是有限的數(shù)量堆上去之后新的 fork 就會(huì)返回EAGAIN。用ps aux | grep Z能一眼看到或者ps -eo stat,pid,ppid,comm | awk $1 ~ /^Z/。處理方式有幾種按場(chǎng)景選同步回收waitpid(pid, status, 0)適合明確知道要等哪個(gè)子進(jìn)程的場(chǎng)合。異步回收注冊(cè)SIGCHLD處理函數(shù)在處理函數(shù)里循環(huán)waitpid(-1, NULL, WNOHANG)直到返回 0 或 -1。注意SIGCHLD可能合并所以必須用循環(huán) WNOHANG不能只 wait 一次。主動(dòng)放棄如果確實(shí)不關(guān)心子進(jìn)程結(jié)果可以顯式忽略signal(SIGCHLD, SIG_IGN)在某些系統(tǒng)上這會(huì)讓子進(jìn)程退出時(shí)自動(dòng)被回收不用父進(jìn)程操心。但要注意這會(huì)影響到所有子進(jìn)程其他需要waitpid的地方就拿不到狀態(tài)了。#include signal.h #include sys/wait.h #include unistd.h static void on_sigchld(int sig) { (void)sig; int saved_errno errno; while (waitpid(-1, NULL, WNOHANG) 0) { /* 循環(huán)回收所有已退出的子進(jìn)程 */ } errno saved_errno; } int main(void) { struct sigaction sa; sa.sa_handler on_sigchld; sigemptyset(sa.sa_mask); sa.sa_flags SA_RESTART | SA_NOCLDSTOP; sigaction(SIGCHLD, sa, NULL); /* ... 業(yè)務(wù)邏輯 ... */ return 0; }信號(hào)處理函數(shù)里保存和恢復(fù)errno是個(gè)細(xì)節(jié)因?yàn)樾盘?hào)隨時(shí)可能打斷正在進(jìn)行的系統(tǒng)調(diào)用處理函數(shù)里如果改了errno回到被打斷的地方邏輯就亂了。SA_RESTART的作用是讓被信號(hào)打斷的系統(tǒng)調(diào)用自動(dòng)重啟減少EINTR的處理負(fù)擔(dān)。另一個(gè)容易被忽略的角色是孤兒進(jìn)程。父進(jìn)程先于子進(jìn)程退出子進(jìn)程就被“過(guò)繼”給initPID 1或者某些系統(tǒng)里的 subreaper由它負(fù)責(zé)回收。這本身不是問(wèn)題但如果你的程序里子進(jìn)程依賴父進(jìn)程做清理工作父進(jìn)程一死子進(jìn)程就成了沒(méi)人管的野進(jìn)程。做守護(hù)進(jìn)程或者熱重啟的時(shí)候要特別小心這一點(diǎn)。5.2 緩沖區(qū)重復(fù)輸出一個(gè)經(jīng)典到不能再經(jīng)典的坑這段代碼把輸出重定向到文件你會(huì)看到兩行hello#include stdio.h #include unistd.h int main(void) { printf(hello); /* 沒(méi)有換行 */ fork(); return 0; }原因在于 stdio 的緩沖策略。輸出到終端時(shí)是行緩沖遇到\n才刷輸出到文件時(shí)是全緩沖緩沖區(qū)滿了才刷。printf(hello)沒(méi)有換行內(nèi)容就躺在用戶態(tài)緩沖區(qū)里沒(méi)發(fā)出去。fork復(fù)制地址空間時(shí)這份緩沖區(qū)內(nèi)容原樣復(fù)制到了子進(jìn)程。父子進(jìn)程各自正常退出exit觸發(fā)刷新于是同一個(gè) hello 被寫(xiě)了兩次。這個(gè)坑的隱蔽之處在于同樣的代碼在終端上跑是正常的一重定向到日志文件就出問(wèn)題。所以排查時(shí)如果發(fā)現(xiàn)“日志里怎么有重復(fù)行”先看看是不是在fork前有沒(méi)刷新的輸出。規(guī)避手段很成熟fork之前調(diào)用fflush(NULL)把所有的輸出緩沖刷干凈或者子進(jìn)程一律用_exit而不是exit或者在每個(gè)printf后面老實(shí)加\n。這三條里我推薦后兩條組合使用_exit應(yīng)該成為肌肉記憶。5.3 常見(jiàn)問(wèn)題速查表把上面這些以及一些零散的問(wèn)題匯總一下方便對(duì)著查現(xiàn)象最可能的原因排查/解決fork返回 -1EAGAIN進(jìn)程數(shù)達(dá)到RLIMIT_NPROC或 cgroup pids 上限ulimit -u查容器 pids.maxfork返回 -1ENOMEM內(nèi)核內(nèi)存不足無(wú)法分配task_struct或頁(yè)表看dmesg、/proc/meminfo子進(jìn)程跑完不退出ps顯示Z父進(jìn)程未回收加waitpid或SIGCHLD處理日志出現(xiàn)重復(fù)行fork 前 stdio 緩沖區(qū)未刷新fork 前fflush(NULL)子進(jìn)程用_exit循環(huán)里 fork 出 2^n 個(gè)進(jìn)程子進(jìn)程落回循環(huán)子進(jìn)程分支結(jié)束后立刻_exit父子寫(xiě)同一文件內(nèi)容錯(cuò)亂共享文件偏移量用O_APPEND或各自 open或分文件子進(jìn)程里加鎖永遠(yuǎn)阻塞多線程下 fork鎖被其他線程持有改成 fork 后立即 exec或用pthread_atfork子進(jìn)程變成孤兒無(wú)人清理父進(jìn)程先退出用 subreaper 或?qū)iT(mén)的 supervisor子進(jìn)程繼承了不該有的 fdfd 默認(rèn)被繼承fork 后關(guān)閉無(wú)關(guān) fd或用O_CLOEXEC最后一條值得展開(kāi)說(shuō)一句。O_CLOEXEC這個(gè)標(biāo)志非常有用打開(kāi)文件或套接字時(shí)帶上它這個(gè) fd 會(huì)在 exec 時(shí)自動(dòng)關(guān)閉避免子進(jìn)程意外持有不該持有的連接。在長(zhǎng)連接多的服務(wù)里如果 fork 出來(lái)的子進(jìn)程繼承了所有 socket一方面浪費(fèi) fd另一方面連接關(guān)閉的時(shí)機(jī)變得難以判斷。從代碼層面統(tǒng)一給open、socket、pipe2加CLOEXEC是個(gè)好習(xí)慣成本幾乎為零。還有一個(gè)排查技巧不確定子進(jìn)程到底繼承了哪些 fd可以在子進(jìn)程里ls -l /proc/自進(jìn)程PID/fd一眼看清楚。同理/proc/PID/status里的Threads、VmRSS/proc/PID/task/下的線程列表都是排查這類問(wèn)題的一手信息。養(yǎng)成看/proc的習(xí)慣比裝一堆工具快得多。6. 我在實(shí)際項(xiàng)目里攢下的幾條經(jīng)驗(yàn)寫(xiě)到這里分享幾個(gè)文檔里不太會(huì)提、但確實(shí)節(jié)省過(guò)時(shí)間的做法。第一給每個(gè) fork 出來(lái)的子進(jìn)程起個(gè)可識(shí)別的名字。Linux 上可以調(diào)prctl(PR_SET_NAME, worker-xxx)這樣ps和top里就能看明白哪個(gè)進(jìn)程在干什么而不是一堆同名進(jìn)程排在那。出問(wèn)題時(shí)省下來(lái)的定位時(shí)間遠(yuǎn)超當(dāng)初寫(xiě)這幾行代碼的成本。第二在子進(jìn)程的入口處打一行帶 PID 的日志并且立刻setpgid或調(diào)整會(huì)話。這能讓日志里的 PID 和進(jìn)程樹(shù)對(duì)應(yīng)起來(lái)尤其是在子進(jìn)程會(huì)再 fork 的場(chǎng)景下沒(méi)有這層標(biāo)記日志會(huì)亂成一鍋粥。做后臺(tái)任務(wù)的時(shí)候順手把子進(jìn)程放到獨(dú)立的進(jìn)程組后面想整組發(fā)信號(hào)終止也方便。第三不要吝嗇waitpid的循環(huán)寫(xiě)法。我見(jiàn)過(guò)太多“只 wait 一次”的代碼在子進(jìn)程密集退出的場(chǎng)景下漏回收慢慢積累成僵尸。統(tǒng)一寫(xiě)成while (waitpid(-1, st, WNOHANG) 0)配合SA_RESTART這套模板可以直接抄。第四大內(nèi)存進(jìn)程優(yōu)先考慮換掉模型。如果發(fā)現(xiàn)每次 fork 都有明顯卡頓先別急著調(diào)內(nèi)核參數(shù)問(wèn)問(wèn)自己“這個(gè) fork 真的必要嗎”。預(yù)派生進(jìn)程池、線程池、獨(dú)立的常駐服務(wù)這三種方案在絕大多數(shù)場(chǎng)景下都比“按需 fork”更穩(wěn)。fork這個(gè)接口看著古老但它承載的語(yǔ)義——地址空間復(fù)制、文件描述符繼承、執(zhí)行流分叉——至今沒(méi)有被替代。把它的返回值、COW、回收機(jī)制這三件事吃透后面再看clone、看容器運(yùn)行時(shí)怎么隔離命名空間、看 shell 怎么執(zhí)行管道都會(huì)順很多。我現(xiàn)在寫(xiě)涉及多進(jìn)程的代碼開(kāi)工前會(huì)先在紙上畫(huà)一遍父子關(guān)系標(biāo)清楚哪個(gè) fd 誰(shuí)負(fù)責(zé)關(guān)、哪條路誰(shuí)負(fù)責(zé) wait畫(huà)完之后 bug 就少了一大半。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国产寻花在线| 99亚洲日韩| 丁香激情五月天| 免费色色色| 五月丁香六月婷婷不卡免费无码| 久久性爱视频网站| 99爱在线| 激情九九这里只有精品| 亚洲精品第一色色色色色色| 亚洲成人乱码av网站| 色五月婷婷青娱乐| 五月丁香色婷婷综合| 丁香激情网| 99视频久久免费视频| 免费V片在线| 五月天另类小说| 天天干天天操天天爱| 五月丁香花激情综合网| 久色大香蕉| 五月天亭亭俺也| 丁香久久| 激情五月天色婷婷| 婷婷丁香五月天在线| 开心婷婷中文字慕| 六月丁香婷婷五月天| 人人操人人添人人摸97| av一区免费看| 色婷婷另类| 99国产精品白浆在线观看免费 | 伊人色综在线| 特级片神马电影| 人人爱操| 婷婷五月激情四月综合| 五月天社区| 久热婷婷在线视频| 天堂五月婷婷| 婷婷久久五月天中文字幕在线观看| 日日夜夜狠狠| 一级片操逼视频| www.五月天| 涩综合网| 色五月人妻| 国产这里只有精品| 久久久99视频| 天天干夜夜想| 538在线精品| 天堂A∨在线| 日本色色色| 日韩精品无码AV| WWW五月| JlZZJlZZ8JlZZ亚洲熟女| 亚洲经典小视频| 狠狠操天天日| 操人妻视频91| 热99一二三| 五月天婷婷乱论小说| 玖玖九九99| 丁香色情五月天| 久久这里这里有精品免费视频| 亚洲欧洲国产精品| 五月天六月天| 色婷婷裸体色性在线| 中文字幕乱轮| 99热超碰天堂网| 任你爽精品免费视频6| 99热6色| 天天天天天久久久久久| 九九干视频| 99精品热| 99精彩视频| 99精品成人无码A片观看金桔| 亚洲情综合五月天| 噜噜狠狠色综合久| 99热无码精品| 色婷婷的五月天| 天天干天天干天天| 国产精品久久久久久久久久| 综合久久六月| 五月综合激情图片| 九九AV在线| 激情五月天影院| 亚洲视频一区| 日韩精品一区二区亚洲AV观看| 色99视频| 色欲色香综合网| 六月综合婷婷开心伊人| 超碰久热| 五月激情射| 五月丁香激情啪啪| Av在线资源| 亚洲久久婷婷丁香五月天| 99欧州偷拍视频| 九月丁香婷婷综合激情| 人人操婷婷| 狠狠色成人影片| 色五月av| 国产精品扒开腿做爽爽爽A片唱戏 亚洲爆乳无码精品AAA片蜜桃 | 久久久网站| 丁香六月婷婷久久综合八月| 少妇2做爰HD韩国电影| 91成人品| 加勒比久热| 色人久久| 26uuu丁香婷婷五月| 久久丁香| 99综合免费视频| 天天干肏夜夜| 色999亚洲人成色| 9 1大香蕉| 香蕉国产2013| 色播五月婷婷| 五月丁香色停停啪啪啪| 天天做天天爱高潮片| 综合色色色色色色| 久草九一| 6080av| 美欧成人视频| 日本久久极品| 婷婷五月视频| 爆乳熟妇一区二区三区四区| 激情五月开心五月在线视频| 婷婷精品在线| 91精品久久久久久久久久久久| 日日干日日s| 久久久五月五丁香| 久热69| 色情久久久| 亚洲无码另类| 色七七九九| 狠狠色丁香久久婷婷综合五月| 99无码视频| 第五婷婷伊人丁香| 9热在线视频精品| 超热久碰.com| 天天日天天爽| 久久综合婷婷五月| 色狠狠综合网| 99热这里只有国产精品| 成人国产欧美大片一区| 五月丁香啪啪啪免费看| 99热最新网址| 91超碰在线观看| 五月丁香啪啪综合| 婷婷色综合| 爽天天天天天天天| 久久99精品久久久久久三级| 俺去也综合| 婷婷丁香五月社区亚洲| 五月丁香免费看| 亚洲三A| 97碰碰视频在线观看| 999精品乱码77777| 一区色色色色网| 天天日夜夜曹| 秋霞日本免费毛片A片| 99热精地址| 香蕉久久国产AV一区二区| 激情五月天婷婷久久久久久久久久久 | 九九99久久| 伊人网碰碰| 影音先锋偷偷色男人站| 97啪啪| 天天噜日日噜综合无码| 激情99。| 任你搞在线观看视频| 无码 色| 性色综合网| 99热激情| 精品九九在线观看视频| 清纯唯美 激情四射| 婷婷黄色五月天在线视频| 色吧五月| 天天综合影院| 日韩色色色色色| 天天干天天干天天干天天干天| 亚洲精品国产成人AV在线| 第四色激情网| 婷婷四色五月| 99热99久久| 色婷婷五月天天天干天天操天天爽| 综合色图区| 婷婷六月丁香激情| 另类国产欧美视频| 98色丁香五月婷婷综合网| 狠狠狠狠狠狠草| 久8色色| 色婷婷四虎| 播播网色播播| 色之综合网| 国产精品久久久久9999小说| 五月婷婷激情网| 欧美色五月| 播五月婷婷开心| 人妻久久久久久| 99热大香蕉| 国产欧美日韩综合精品一区二区| 夜丁香综合| 综合狠狠干| 99热这里只有精品4| 五月婷久久| 丁香六月欧美| 亚洲乱码精品久久久久..| 久久黄色片| 91日本在线观看| 麻豆AV一区二区三区| 五月天婷婷中文字幕在线播放| 欧美日本黄色| 狠狠综合久久综合| 蜜乳久AV| 99久视频| 啪啪99| 情五月亚洲婷婷| 丁香伊人五月色婷婷五十路| 国产在线aaa片一区二区99| 99这里只有精品99| 天天做天天要天天爽| www,色综合| 综合网激情| 日本五月婷| 免费的日逼视频| 久久一操| 综合99在线| 久久久久人妻精品| AV在线观看网站| 亚洲九九99精品视频在线播放| 狼友超碰| 天天色99| 99热九九这里只有精品10| 一区中文字幕电影| 天天干天天干天天干天天干天天| 国产成人精品一区二区三区视频 | 色播五月婷婷| 99热亚洲| 五月婷婷丁香| 色欲午夜无码久久久久久张津瑜| 婷婷D区| 九九免费精品在线视频| 五月天综合网| 啪啪综合网| 五月天综合色| 婷婷久久婷婷色五月| 噼里啪啦在线观看免费完整版视频 | 亚洲字幕AV一区二区三区四区| 色伊人婷婷| 丁香综合日产精品久久| 日日操天天| 激情网站综合五月天| 欧美超级视频97| 日日狠狠久久偷偷四色综合免费| 色婷婷九月综合| 99re思思精品视频在线观看| 丁香久色| 麻豆五月丁香婷婷| 热久视频| WWW久久久| 久久99热在线观看| 国产毛多水多女人A片| 国产激情在线| 久久性刺激| 开心激情五月天网| 丁香 久久| 播播网色播播| 97干在线| 9+1视频网址| 色五月激情五月| www.99视频| 九九热av| 嫩草AV久久伊人妇女超级A | 精品五月花| 久操乱| av高清无码| 97五月天婷婷午夜| 丁香花五月天激情| 吉澤明步Av一區二區| 伊人婷婷五月天av| 国产精品色| 午夜成人综合| 超碰99热| 超碰chaompinm| 色婷婷激情| 六月婷婷色综合| www.天天日| 婷婷另类小说| 99热每日| 色婷婷久久综合| 综合色99| 99热在线观看免费| 久久综合激情| 色五月综合激情网| 99热网址| 亚洲婷婷月丁香五月| hd五月婷婷在线| 五月丁香婷婷开心| 91精品综合久久久久久五月丁香| 九月丁香久久网| 九九美女视频| 99这里只有精品国产| 另类激情五月| 99热亚洲| 日本wwww在线| 天天日天天干天天爱| 噜噜久| 97精品自拍视频| 天天干一干| 色婷婷狠狠久久综合五月| 久热久操久热久草国产91| 99色在线视频| 综合久久五月天| 丁香六月婷婷综合| 《丁香激情综合久久伊人久久》影视在线观看 -高清预告手机免费播放 -三妹影院 | 九九视频这里有精品| 日本天堂免费99| 另类专区在线观看| 色久影院| 日日舔夜夜操| 国产高潮A片羞羞视频涩涩| 国产三级在线播放| 亚洲色婷婷网站| 少妇综合网| 五月婷婷综合网| 91丨九色丨熟女|老版| 婷婷五月天电影网 | 激情綜合網址| 色网站9| 亚洲天堂aaa| 亲子乱AV一区二区三区下载| 99re在线免费视频| 五月综合影院| 色久婷婷五月| 欧美成人网婷婷综合在线| 91日视频| 人妻Av在线| 蜜乳9188| 99re6久热只有精品6在线直播| 9 7总站超级碰免费视频| 大香蕉综合在线| 99热免费看| 国产精品人成A片一区二区| 狠狠色狠狠爱| 91919191919久久成人视频| 丁香六月婷婷久久综合| 狠狠做五月| 婷婷五月情| 字幕网AV中文字幕| 丁香婷婷射| 日韩aaaaa| 日本婷久久| 丁香五月婷婷在线观看| 九九热内射| 亚洲看av的网站| 婷婷五月天伊人网| 五月天无码| 97资源碰碰| 一起草aV| 亚洲综合色网| 人人综合久| 色444综合网| 天天摸,天天爽| 日本五月婷婷| 天天做天天双| 婷婷97色| 五月婷六月婷婷| 狠狠色丁香乆乆| 26UUU在线观看| www.色婷婷| 天天爽成人综合网站| 99热最新网址| 婷婷五月综合婷婷| 亚洲日本韩国| 色丁香影院| 伊人大香蕉毛片| 色色丁香激情五月| 五月天婷婷影院影院观看| 日本啪啪天堂| 国产精品久久久久9999小说| 五月天激情影院| 97人人干人人操| 中文字幕视频在线播放| 色婷婷丁香五月| 99精色| 天天综合色| 1区2区视频| 九色无码| 丁香五月婷婷少妇| 国产欧美大香蕉一区| 五月天婷婷激情在线色图| 伊人久热91| 97婷婷丁香| 五月天激情影院| 丁香九月激情| 精品久久久中文字幕大豆网推荐理由| 亚洲啪啪网| 这里只有精品免费视频| 婷婷四色成人综合色视| 999久久久国产精品| 五月婷婷激情网| 99在线观看视频蜜臀| 五月天丁香久久综合 | 五月天激情在线视频| 7777国产盗摄农村女人| 玖玖爱资源站| 色五月色五天色情网| 懂色av蜜臀av粉嫩av永陈冠希 | 婷婷精品视频| 1024成人免费看| 丁香婷婷情色五月天| 五月婷在线观看| 99国产精品久久久久久久久久久 | 狠狠色综合五月| 九九久久精品國產| 亚洲精品又粗又大又爽A片| 久久婷婷操| 玖玖婷婷色五月| 亚洲成人网站在线观看| 色噜噜狠狠一区二区三区| 秋霞性爱AV| 人妻第九页| 91se在线观看| 五月天综合影院| 97婷婷色| 91日日日| 亚洲AV永久无码影院黑人| 亚洲精品大片| 丰满人妻一区二区三区| 丁香六月激情蜜桃| 色婷婷内射| 五月叮香啪| 99热高清在线| 激情婷婷狠狠干综合| www.久久色.com| 五月丁香婷婷六月天| 婷丁香五月天| 超碰超碰在线| Caoub青青超碰| 亚洲无码色色| 九九热中文| 蜜乳中文字| 91操熟女| 久久九色| 成人婷婷| 丁香 久久| 亚洲岛国电影| 万月丁香狠狠爱| 午夜色婷婷| 成人AV中文字幕| A A色色| 色婷婷XXXXX| 色天使色婷婷| 丁香六月色婷婷| 九九热青青草| 国产亚洲av片| av超碰在线| 人与禽A片啪啪| 亚洲五月婷婷| 色色色色色色网站| 久久婷婷视频| 九九热最新| 玖玖在线视频| 26uuu精品一区二区| 国产.亚洲.欧洲视频在线| 狠色色狠网| 可以直接看的AV网站| 青青操绿aaa一区日v| 日韩综合网络男女香蕉a片| 拳交大逼| 日本熟女一区二区| 丁香五月六月婷婷殴美综合| 99国产这里只有精品| 日日操,天天操| 久久五月天激情视频| 欧美色色色色色色色色色色影视| 婷婷六月综合在线| 五月丁香 啪啪啪| 天天操夜夜玩!| 五月天激情婷婷五月天久久| 欧美激情凹凸丁香网| 丁香婷婷伊人| 婷婷色五月婷| 综合网色| 色噜噜狠狠色综无码久久合欧美| 国产真实乱了老女人视频| 99精品视频在线观看| 内射人妻视频国内| Y11111111111少妇电影院| 丁香六月天婷婷| 一操久久| 伊人春天av| 激情99。| 欧洲第一无人区观看| 婷婷天堂站| 日本三级中文字幕| jiujiu热在线视频| 九月婷婷丁香| 99在线精品视频| 九九热AV| 三日本无码| 色婷婷综合综合网| 久久九九囯产| 99re熱| 激情综合网,婷婷| 婷婷五月丁香色情| 日韩黄色电影| 成人国产欧美大片一区| 青青操丝袜美腿| 色婷婷九月| 六月婷婷色五月| 欧美丁香婷婷五月天| 9精品在线| 五月丁香直播| 色综合久久天天综合网| 蜜乳A√| 中文AV网站| 色婷婷综合网| 婷婷94s| 97人凄人人操人人爽| 日日噜狠狠色综| 婷婷婷婷色| 色婷婷丁香| 四季日韩AV无码综合| 99操碰| 婷婷五月天成人综合网| 丁香五月婷久久| 免费91久久精品| 激情综合在线观看| 丁香五月婷婷激情中文| 99热在线播放| 色五月天丁香婷婷| 天天操电影院色狼性av| 国产69久久久欧美黑人A片| 婷婷五月a| 色婷婷五月天激情在线播放| 97视频久久| 婷婷丁香久久网| 就是色婷婷五月亚洲色| 天天综合 99久久婷婷| 久久精品国产精品| 久久这里在精品视频| 五月丁香综合影院| 奇米影视777在线_在线观看午夜_h小视频在线观看_岛国大片 | 人妻激情久久| 久久五月丁香伊人青草| 丁香花色色网| 三级毛片7979| 五月婷婷官网色| 精品久久久久成人码免费动漫| 超碰人人操在线| 亚洲天堂aaa| 成人精品视频99在线观看免费| 日本九九视频| 五月丁香五月婷婷| 99热官网精品在线| 亚洲人成人五月天| 蜜臀久久99精品久久久久久酒店| 五月丁香婷婷无码A∨| 狠狠99| 亚洲蜜乳AV| 97在线刺激| 青草少妇激情| 思思久热6| 日日做夜夜爱| 在线免费视频caop| 天天拍久久| 激情五月综合第一页| 日日操夜夜爽天天天| www.夜夜| 五月天婷五月天综合网小说首页-五月天激激婷婷大综合,婷婷亚洲综合五月天小说 | 99热在线观看| 清色五月天| 俺去也婷婷| 99r这里只有精品哦| 婷婷99狠狠| 色综合九九| 日韩综合久久| 91天天操天天干天天射| 亚洲高清在线| 中文字幕丰满乱孑伦无码专区| 久热婷婷| 激情五月第四色| 天天草天天日| 丁香五月激情鲁| 婷婷五月天A V| 欧美97p| 久久婷婷六月综合国际| 亚洲AV色婷婷人禽五月天| 九九色插| 婷婷五月在线视频| 亚洲五月婷婷| 婷婷99狠狠躁天天躁| 99re这里只有精品免费| 淫五月停停| 日日夜夜小色哥| 九九成年视频| 站长推荐无码播放| 4399在线观看免费高清电视剧| 激情综合五月| 天天免费日日夜夜夜夜| av无码电影| 日本超碰在线| 婷婷丁香午夜综合影视| 嫩草哈哈操| 香蕉视频91| 做爱夜夜干天天操| 熟妇天天综合| 日本色色网| 婷婷激情蜜桃玖玖丁香| 久久婷婷六月综合综合| 五月天激情小说| 日日干夜夜撸夜夜骑| 久久99网| 一起草av| 亚洲人妻五月丁香婷婷| www.99热视频| 亚洲欧洲另类图片| 丁香婷婷六月天| 亚洲五月婷婷在线| 日本欧特黄色刺激一区影视久精品无码| 日本久热| 五月丁香AV在线| 内射综合网| 99精品在| 亚洲激情四射色| 婷婷五月成人有| 九九Av| 天天天摸夜夜夜玩| 久操热| 26uuu成人网| 成人午夜无码视频| 五月丁香六月激情| www.狠狠操.com| CHINESE熟女老女人HD视频| www.五月婷婷久久.com| 婷婷五月电影| 色婷婷AV久久| 69精品人人人人| 丁香婷婷月| 国产寻花在线| 亚洲另类在线观看| 五月丁香综合中文| 成人av在线网| 开心久久xxx色| 91人人操人人| 激情丁香六月| 婷婷丁香六月激情综合| 日本三级黄色大片| 婷婷午夜综合| sewuyuetingtingiii| 国产精品日本一区二区在线播放| 超碰人人艹| www,天天干| 色五月婷婷丁香婷婷| 人妻av在线| 九九热婷婷| 99热在线播放精品| 97一区二区| 九九AV| 91日韩在线| 五月亭亭开心网| 婷婷丁香色五月久久88| 伊人狠狠综合| 97色色色色色色色色色色色色色| 亚洲天堂亚洲色色色| 久99久视频| 精典久久| 色婷婷丁香综合中文字幕| 99热 在线播放| 丁香操逼| 色色草97| 91av视频在线观看最新网址| 日韩 mm 不卡| 色色色色色色色色色色色色色五月天| www。五月,com| 九九婷婷五月天| 亚洲国产精品VA在线看黑人| 欧美成人精品A片免费一区99| 97久久久| 99在线精品免费视频| 人妻久久久久久| 人人播| 性色欲情 网站| 婷婷亚洲色| 超碰色色综合| 丁香激情久久| 99热精品中文字幕| 97香蕉碰碰人妻国产欧美| 五月婷婷色五月| 婷婷五月天色播| 色色色999| 国产成人精品一区二区三区视频| 中文字幕乱码亚洲精品一区| 伊人九九68| 九九Y精品热播| 97人操| 激情五月综合网最新| WWW.99热| 视频免费精品免费精品免费精品免费精品免费精品免费精品免费99 | 日本美女五月天| 婷婷涩涩五月天| 玖玖99免费视频| 九月影院義母在线播放| 99精品大片| 天色色综合网| 天天做天天爱天天高潮| 无遮挡国产高潮视频免费观看| 99热久久这里只有精品| 色99综合色88| 成人在线网站| 精品婷婷五| 91九色精品熟女内射| 成人精品在线观看| 色色色网站| 激情综合色五月丁香| 五月婷婷97| 超碰91av| 丁香婷停五月激情综合深爱| 99精品在这里| 亚洲综合激情五月久久| 男同91| 丁香激情五月少妇| 快乐婷婷五月天| 色婷婷激情五月天在线观看| 婷综合| 少妇AB又爽又紧无码网站| 婷婷夜夜夜夜| 伍月婷丁香婷| 青青草成人网| 免费观看18视频网站| 久久精品无码一区| 九九色人| 亚洲aV写真天天综合网久久| 婷婷五月激情丁香| 欧美123区免| aaa丁香五月天| 热思思| 99久久综合网| 丁香五月天激情四射网| 婷婷五月天少妇| 99riAv1国产在线观看| 一二线视频 另类| 婷婷的99视频网站| 色五月婷婷影院| 久久99久久99久久99人受| www.99免费视频| 婷婷五月天色综合翘| 99热热这里只精品996小说| 国产精品激情AV久久久青桔| 中文无码婷婷| 停婷丁五月在线| 亚洲欧美日韩VIP| 日本欧美在线| 狠狠干狠狠干| 久久婷五月影院| 秋霞学生妹一二级| 久久久婷婷婷| 超碰猛烈的性猛交| 五月天天爱| 欧州婷婷五月天综合| 色噜噜狠狠色综合无码久久欧美| 播五月,色五月,开心五月播放器| 色和综合网| 丁香五月狠狠在线观看| 久久99婷婷| www,超碰| 婷婷五月天国产| 婷婷九月久久| 99热这里只有精品1998| 蜜桃人妻无码AV天堂三区 | 五月天激情综合网俺也去| 婷婷激情六月| 超爽内射| 婷婷五月色情天| 丁香五月激情啪啪综合| 人妻 性久久久久久| 人人草成人视频| 9热精品| 99人人操人人操人人精| 狠狠高潮精品亚洲1| 五月综合激情啪啪啪啪啪| 色婷婷婷婷成人网| 疯狂做受XXXX高潮A片动画| 婷婷成人综合| 俺去也婷婷| 亚洲午夜精品久久久久久人妖| 激情四射网| 国产免费一区二区三州老师F1F1| 99免费在线视频| 热的五码久久精品| www.婷婷五月天| 日本人妻伦在线中文字幕| 99热无码精品| 三十熟女| 这里只有精品69| 日日操夜夜操不卡| 激情欧美五月丁香| 夜夜干天天干| 六月综合婷婷开心伊人| www狠狠爱com| 九九热视| 秋霞AV淫| 五月丁香婷婷综合| 天天操夜夜啊| www。久久久久一b。Cc| 午夜婷婷五月天| 五月丁香六月婷婷激情四射| 天天草天天爽| 欧美日朝成人| 国产精品天天狠天天看| 色五月丁香五月婷婷五月成人网| 97操男人的天堂| 色色色色色色色色色色色色色97| 婷婷五月天激情网| 婷婷精品视频| 婷婷五月六月丁香综合| 黄涩毛片| 亚洲激情四射| 日本ww亚洲| 五月色情婷婷| AV在线观看网站| 思思99精品视频在线观看| W色综合| 可以看的av| www.激情.com.| 婷婷情色开心五月天99| 日本天天色| 思思视频久久| 婷婷五月天丁香久久| 亚洲中文av| 五月丁香六月合| 九九色院| 成人综合网站| 天天爱天天爽| 夜夜躁狠狠| 97操在线资源| 99爱爱| 丁香色五月婷婷| 日本综合久| 奇米色大香蕉| www.婷婷五月天| 99热国产这里只有精品| 播五月婷婷开心| 久久女人九九| 99热国内| 九色无码| 激婷网| 亚洲欧美成人在线| 五月激情婷婷女| 五月丁香美女视频| 97碰碰人人视频| 香蕉综合网| 九九精品亚洲| 婷婷六月天激情影院| 婷婷的99视频网站| 亚洲性爱AV| 开心激情婷婷| 色综合久久99色| 五月久久丁香| 热久久77777| 一本久道综合99| 免费碰碰视频久| 天天日综合| 日日夜夜天天| 婷婷六月伊人| 色色色视频| 婷婷的99视频网站| 色婷婷色| 中文AV网站| 国产毛片欧美毛片久久久| 激情久久久久| 久久久久久久人妻| 亚洲色婷婷视频| 天天综合干| 丁香婷婷六月激情文学| 九艹在线| 狠狠久久婷婷| 亚洲啪| 丁香五月婷婷综合啪啪| 深爱 五月天| 在线观看免费狠狠色丁香香综合| 丁香六月综合| 久99在线| 久久九九激情五月天 | 伊人五月婷婷国产视频| 七月丁香婷婷 色色| 公的粗大挺进了我的密道 | 欧美私人家庭影院| 伊人久久婷婷| 岛国av网站| 日韩九九| 色播五月| 天天色视频| 丁香五月电影| 99热精品中文字幕| 国产成人99久久亚洲综合精品| 91婷色| 九九99热久久精品66中文字幕| 色五月激情| 婷婷操婷婷干婷婷射| 99国产视频网| 色婷婷五月视频| 激情综合激情五月一起草| 亚洲丁香五月| 激情五月天无人视频在线| 1995年关宝慧版蜘蛛女| 久久这里只有精品网| 狠狠色无码| 思思久日精品视频| 五月丁香六月婷婷久久| 99热在线观看免费精品| 激情九色| 久婷| 综合网亚洲| 天天综合精品| 久久AAAA片一区二区| A片试看120分钟做受图片| 国外亚洲成AV人片在线观看| 色综合99无码 | 色色综合网络| 五月天婷婷社区| 久婷婷婷| 色色色五月婷婷| 日本欧美成人片AAAA| 色色色色色色综合网| 婷婷五月另类网站| 91超级碰在线| 婷婷,五月天,丁香,第一| 九九成人| 综合AV网| 婷婷五月丁香色播| 大香蕉av在线| 狠狠操天天操综合| 五月婷婷六月开心| 久久激情五月天| 99久在线精品99re8热| 久久AV无码精品人妻系列试探| 91狼友视频网页更新| 五月天丁香综合在线| 亚洲综合色婷婷| 丁香五月骚喷水视频| 亚洲AV色婷婷人禽五月天| 91九色熟女| 亚洲乱码日产精品BD| 色综合久久8| 日本99久久| 丁香五月天激情综合网| 黄色一级影片| 精品人妻伦九区久久AAA片| 99热九九九九| 五月天婷婷基地| 六月色国内综合| 99啪| 黄色国久久| 婷婷综合亚洲| 五月婷婷影视| 国产97色在线| 国产精产国品一二三在观看| 91久久久久久久久久| 99在线视频免费| 五月丁香六月婷婷激情视频在线观看免费 | 丁香啪啪| 婷婷五月视频| 就要去操亚洲成人精品五月天丁香婷婷| 热热久久久久久久久| 99操免费视频| 色婷婷呢狠禁久禁| 热九九精品| 天天久综合| 五月天偷拍| 婷婷 伊人 久久| 襙比视频| 婷婷丁香人妻天天爽| 丁香六月亚洲| 日韩狠狠色婷婷| 9热久久| 91操在线视频| 亚洲丁香五冃97色| 97人人草| 色噜噜狠狠狠综合曰曰曰| 五月婷久久| 激情五月天第四色| 丁香婷婷久久老熟女综合网| 岛国AV网| 99色精品| 欧美美美女性色视频| 亚洲中文字幕在线观看| 激情五月婷婷综合| 99热这里都是精品| 婷婷五月欧美| 亚洲综合999| 色婷婷六月天在线| 极品人妻VIDEOSSS人妻| 欧美精品99| 色五月欧美| 亚洲一区二区 成人网站戴套| 欧美成人热| 色五月丁香婷婷| 日本久久爽| 色综合天天综合成人网| 香蕉曰比| 热99re| 国产欧美精品AAAAAA片| 久久五月天激情婷婷| 影音先锋一区二区三区| 丁香六月婷婷色播| 丁香五月天激情视频| 欧美精品狠狠色丁香婷婷| 五月丁香在线婷婷蜜桃| 国产精品美女久久久久AV超清| 亚洲操逼网| 九九青青草成人| 开心久久五月天| 五月天婷婷无码| 丁香婷婷五月综合色情| 人妻精品在线| 精品久久久999| 五月婷婷激情性爱| 久久丁香五月| 超碰超碰在线| 婷婷四色五月| 啪啪综合网| 丁香婷婷六月激情文学| 婷婷综合激情| 久鲁鲁色网| 五月丁香网站| 丁香婷停五月激情综合深爱| 影音先锋91网站在线观看| 丁香婷婷久久激情| 婷婷99狠狠躁天天久久久九九九| 狠狠色丁香婷婷综合久久97AV| 一本大道伊人AV久久综合| 天插天啪天啪天啪| 五月做爱| 婷婷五月天美女21p| 26.uuu丁香五月婷婷| 超碰人人操人人干| 婷婷色激情网| 日日做A爰片久久毛片A片英语| 可以直接看的av网站| 91麻豆国产三级精品福利在线观看| 色婷婷五月天堂资源| 91九九热| 日本在线视频播放91| 亚洲天堂久久| 五月婷婷激情综合| 国产性色蜜乳| 婷婷新网址| 九色自拍| 亚洲精品乱码久久久久久综合| 欧美亚洲色色色色| 这里只有精品在线观看视频| 久久九九99桃花视频| 国产亚洲在线观看| 激情综合激情五月| 黄色毛片精品| 日本久久精品| 婷婷五月精品在线| 色久99| 丁香五月天啪啪| 日日操人人操| WWW99热| 少妇高潮呻吟A片免费看软件 | 97五月天| 亚洲成人色五月天| 丁香九月激情在线视频| 欧美色99| 激情五月婷婷在线区| 大香蕉啪啪啪啪啪啪| 五月天久久婷婷| 99er久久| 色墦五月丁香| 人妻免费网站| 亚洲午夜AV| 婷婷色Av| 五夜婷婷| 男同色五月开心五月激情五月| 五月婷婷偷拍| 26uuu国产精品| 久热AA| 91性交在线播放| 久婷| 玖玖资源站蜜臀| aⅤ79成人片| 影院久久久| 六月激情婷婷| www.色婷婷.com| 69婷婷丁香午夜| 五月丁香色综合| 亚洲区视频| 雪千夏麻豆| 婷婷五月婷婷| 天天综合网站| 亚洲精品字幕| 5月婷婷6月丁香aV| 婷婷五月色影视先锋| 综合色在线| 久久九九热视频| 五月亚洲| 在线观看免费狠狠色丁香香综合| 色五月色综合| 激情五月天婷婷色色色色色色色色色色色 | 丁香五月成人社区| 色综合天天网| 亚洲午夜av| 日韩无码系列| 曰韩五月丁香色婷婷无码| 婷婷性爱| 深爱婷婷网| 亚洲人成色A777777在线观看| 亚洲综合婷婷五月天| 五月天另类小说亚洲| 婷婷久久五月天丁香| 欧美日本99| www.91五月| 丁香六月婷婷久久综合| 在线观看中文字幕亚洲| www.minyis.com【JT】实力收量可预付QQ2101460746 | 五月婷婷激情五月| 婷婷亚洲在线| renrencaoav| 无码免费人妻A片AAA毛片西瓜| 丁香婷婷天堂| av大香蕉| 丁香五月在线| 夜夜大香蕉婷婷丁香| 婷婷久久色| 丁香五月婷综合网| 丁香五月激情综合啪啪| 操日本人妻视频| 日韩五月天婷婷| 婷婷激情综合色五月久久,色婷婷丁香花,丁香婷婷五月情天,久久婷婷五月综合色 | 五月天婷五月天综合网在线观| www.超碰在线| 中文字幕在线日亚洲9| 日本欧美国产| www999日韩精品| 九九热99视频在线| 丁香五月最新地址| 婷婷天堂视频| 六月婷婷久久| 天天搡日日搡aaaaⅩ| 欧美在线看| 99热综合在线| 亚洲精品成人| 久热只有这里有精品| 九玖视频这里只有精品| 五月六月婷婷激情网| 欧美性二区| 伊人五月天日日夜夜久久久天天| www.粉嫩av.com| 色婷婷视频| 丁香五月天欧美在线| 久久这里只有国产精品视频| 日本成人噜噜| 99热a片免| 久久久婷婷五月亚洲97号色| 伊人久久大香网| 婷婷五月天丁香| www.婷婷| 七月婷婷色香综合网| 久久九九热38| 1024你懂的欧美曰韩| 婷婷五月天黄色网址| 九九久久99| 好吊操这里只有精品| 99热骚货| 久久爱婷婷| 日日干天天射| 色九月| 丁香五月亚洲综合丝袜| 在线综合91| www.99热视频| 日韩一66精品| 五月婷婷丁香在线| 99久久婷婷五月综合| 97色色婷婷| 极品人妻VIDEOSSS人妻| 久久日婷婷| 五月婷婷天堂| 激情精品久久| 99热这| 天天色宗合| 五月婷婷色色爱| 操逼巨乳91| 9.1综合网| 色色网五月激情| 超碰精品在线| 激情内射人妻1区2区3区| 91 九色 入口| 婷婷综合激情五月中文字幕| 天天天天天天噜| 婷婷91| 激婷网| 天天噜日日噜综合无码| 亚洲天堂AAA| 日韩黄色电影| 欧美成人AAA片一区国产精品| 日韩成人综合| www.夜夜操.con| 五月天综合色| 2018国产大陆天天弄| 丁香九月激情久久| 久色视频首页| 月色色综合婷婷网| 99视频这里只有免费精品| 色日本网| 激情五月综合| 91九色无码内射| 亚州激情网站无码| 99热这里只有精品8| 麻豆AV一区二区三区| 丁香五月开心亚洲| 婷婷狠狠五月综合| 狠狠色综合网| 91啦丨九色丨刺激中文| 九九视频免费| 五月天婷婷成人网| 9久热精品在线视频| 亚洲美女高潮久久久久久69| 日日操,夜夜撸| www.婷婷五月天| 99WWW免费视频| 婷婷五月天亚洲综合| 操一区| 九热精品| 久久激情五月婷婷| 成人超碰网| eeuus五月婷| 久热人妻| 亚洲爱婷婷| 五月六月激情| 疯狂做受XXXX高潮A片动画| 久热人妻| 丁香五月成人婷婷| 91狼友视频在线观看| 性爱在线播放av| 任你爽视频| www.91在线观看| 99在热线免费视频| 级人人91| 97干婷婷五月天| 婷婷五月天丁香| 色欲人妻综合aaaaaaaa网| 生活片五区| 99超级碰碰| 综合图片色色| 99五丁香月| 久久这里99| 青草视频在线播放| 五月激情婷婷开心五月| 另类视频五月天| 综合婷婷| 丁香婷婷久久| 亲子乱AV一区二区三区下载| 女人被男人吃奶到高潮| 婷婷激情啪啪| 五月激情婷婷丁香天堂| 碰碰碰碰碰99| 丁香五月激情综合啪啪| 久婷狼色诱惑在线| 婷婷六月天亚州| 69热91天堂| 五月天婷a| 国产免费一区二区三州老师F1…… | 九月丁香五月婷婷| 黄色av高清| 色色 亚洲| 色色丁香色五月| 停婷丁五月在线|