本篇內(nèi)容主要講解“PHP程序員都應(yīng)該知道的進(jìn)程知識有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“PHP程序員都應(yīng)該知道的進(jìn)程知識有哪些”吧!
雄縣網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),雄縣網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為雄縣上千多家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請找那個售后服務(wù)好的雄縣做網(wǎng)站的公司定做!
先說說進(jìn)程和線程,進(jìn)程是操作系統(tǒng)資源分配的最小單元,是程序執(zhí)行的一個實例。在程序運行時系統(tǒng)就會創(chuàng)建一個進(jìn)程,并為它分配資源,然后把該進(jìn)程放入進(jìn)程的就緒隊列,這樣進(jìn)程調(diào)度器選中它的時候就會為它分配CPU時間片。
進(jìn)程的狀態(tài)有:新建態(tài)、就緒態(tài)、運行態(tài)、阻塞態(tài)、退出態(tài),狀態(tài)之間可以進(jìn)行轉(zhuǎn)換:就緒->運行,運行->就緒,運行->阻塞,阻塞->就緒
①新建態(tài)新建態(tài)進(jìn)程剛創(chuàng)建的時候的狀態(tài)。創(chuàng)建進(jìn)程時,首先由進(jìn)程申請一個空白的進(jìn)程控制塊(即PCB),并向PCB中填寫用于控制和管理進(jìn)程的信息;然后為給這個進(jìn)程分配運行時需要的資源;最后把該進(jìn)程轉(zhuǎn)入就緒狀態(tài)并插入到就緒隊列中。
②就緒態(tài)就緒態(tài)是指有等待執(zhí)行的進(jìn)程,有執(zhí)行資格,還沒有執(zhí)行權(quán)限。有執(zhí)行資格是指已經(jīng)分配到除了CPU之外的所有必要的資源,沒有執(zhí)行權(quán)限是因為還沒有獲得CPU。
③運行態(tài)運行態(tài)的進(jìn)程是指進(jìn)程獲得了CPU,既有執(zhí)行資格,又有執(zhí)行權(quán)力,處在正在運行的狀態(tài)。在單處理機(即CPU)系統(tǒng)中,同一時刻只能有一個進(jìn)程處于運行態(tài)。在多處理機系統(tǒng)中,同一時刻可以有多個進(jìn)程處于運行態(tài)。
④阻塞態(tài)阻塞態(tài)是指進(jìn)程執(zhí)行的過程中遇到阻塞暫時無法繼續(xù)運行,就會轉(zhuǎn)向阻塞態(tài)。進(jìn)程阻塞的原因有I/O請求、時間片用完、遇到一些錯誤等。
⑤退出態(tài)即進(jìn)程停止運行。進(jìn)程到退出態(tài)的原因有:程序執(zhí)行完成、調(diào)用退出函數(shù)、遇到錯誤、接收到終止的信號、進(jìn)程被操作系統(tǒng)殺掉等。進(jìn)程退出時,操作系統(tǒng)會將進(jìn)程的PCB清零,并將PCB空間返還給系統(tǒng)。進(jìn)入終止態(tài)的進(jìn)程以后不能在再執(zhí)行,但是操作系統(tǒng)中任然保留了一個記錄,其中保存狀態(tài)碼和一些計時統(tǒng)計數(shù)據(jù),供其他進(jìn)程進(jìn)行收集。一旦其他進(jìn)程完成了對其信息的提取之后,操作系統(tǒng)將刪除其進(jìn)程,即將其PCB清零,并將該空白的PCB返回給系統(tǒng)。
說完進(jìn)程再說說線程,線程是CPU調(diào)度的最小單位,同時線程也是一個有限的系統(tǒng)資源。一個進(jìn)程可以由多個線程組成,線程之間共享進(jìn)程的所有資源,每個線程有自己的堆棧和局部變量。線程由CPU獨立調(diào)度執(zhí)行,在多CPU環(huán)境下就允許多個線程同時運行。同樣,多線程也可以實現(xiàn)并發(fā)操作,每個請求分配一個線程來處理。
線程的狀態(tài)和進(jìn)程類似,一個進(jìn)程可以運行多個線程,多個線程可以共享數(shù)據(jù)。只不過線程之前切換消耗的CPU資源比進(jìn)程切換要小。
與進(jìn)程不同的是同類的多個線程共享進(jìn)程的堆和方法區(qū)資源,但每個線程有自己的程序計數(shù)器、虛擬機棧和本地方法棧,所以系統(tǒng)在產(chǎn)生一個線程,或是在各個線程之間作切換工作時,負(fù)擔(dān)要比進(jìn)程小得多,也正因為如此,線程也被稱為輕量級進(jìn)程。
進(jìn)程和線程之間有什么區(qū)別呢?
本質(zhì)區(qū)別:進(jìn)程是操作系統(tǒng)資源分配的基本單位,而線程是CPU任務(wù)調(diào)度和執(zhí)行的基本單位。
空間和資源:進(jìn)程之間相互獨立,統(tǒng)一進(jìn)程內(nèi)的線程之間可以共享資源。不同進(jìn)程中的線程相互獨立。
切換開銷:進(jìn)程之間有自己獨立的代碼段和數(shù)據(jù)空間(程序上下文),進(jìn)程之間的切換需要保存上下文、寄存器等數(shù)據(jù),會有較大的開銷;同一個進(jìn)程中的線程共享代碼段和數(shù)據(jù)空間,每個線程都有自己獨立的運行棧和程序計數(shù)器(PC),線程之間切換的開銷小。
相互關(guān)系:進(jìn)程崩潰后,在保護(hù)模式下不會對其他進(jìn)程產(chǎn)生影響,但是一個線程崩潰整個進(jìn)程都會掛掉。
執(zhí)行順序:進(jìn)程有自己的程序運行的入口、順序執(zhí)行序列和程序出口。但是線程不能獨立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個線程執(zhí)行控制,兩者均可并發(fā)執(zhí)行。
介紹進(jìn)程之間通信之前先介紹一個概念:用戶態(tài)和內(nèi)核態(tài)。
當(dāng)一個進(jìn)程在執(zhí)行自己的代碼時處于用戶態(tài),當(dāng)這個進(jìn)程因為系統(tǒng)調(diào)用陷入內(nèi)核代碼中執(zhí)行時處于內(nèi)核態(tài)。執(zhí)行的內(nèi)核代碼會使用當(dāng)前進(jìn)程的內(nèi)核棧,每個進(jìn)程都有自己的內(nèi)核棧。
當(dāng)用戶運行一個程序時,該程序創(chuàng)建的進(jìn)程開始時運行自己的代碼,處于用戶態(tài)。如果要執(zhí)行文件操作、網(wǎng)絡(luò)數(shù)據(jù)發(fā)送等操作必須通過write、send等系統(tǒng)調(diào)用,這些系統(tǒng)調(diào)用會調(diào)用內(nèi)核的代碼。進(jìn)程會進(jìn)入內(nèi)核地址空間去執(zhí)行內(nèi)核代碼來完成相應(yīng)的操作,內(nèi)核態(tài)的進(jìn)程執(zhí)行完后又會回到用戶態(tài)。這樣,用戶態(tài)的程序就不能隨意操作內(nèi)核地址空間,具有一定的安全保護(hù)作用,保證進(jìn)程間的地址空間不會互相沖突,一個進(jìn)程的操作不會修改另一個進(jìn)程地址空間中的數(shù)據(jù)。
進(jìn)程從用戶態(tài)切換到內(nèi)核態(tài)常見的有三種方式:系統(tǒng)調(diào)用(如fork調(diào)用)、異常(如缺頁異常)、外圍設(shè)備中斷。
下面說說進(jìn)程間通信,即IPC,全稱是InterProcess Communication。不同進(jìn)程之間可以相互通信、交換數(shù)據(jù)。進(jìn)程之間通信方式有:管道(包括無名管道和命名管道)、消息隊列、信號量、共享內(nèi)存、Socket、Streams。
①管道:管道又分無名管道和有名管道,無名管道是單向的,只允許單向通信。如果需要雙向通信,就需要開啟兩個單向管道。有名管道是在文件系統(tǒng)目錄中存在一個管道文件。管道文件僅僅是文件系統(tǒng)中的標(biāo)示,并不在磁盤上占據(jù)空間。在使用時,在內(nèi)存上開辟空間,作為兩個進(jìn)程數(shù)據(jù)交互的通道。
②消息隊列:消息隊列是由消息的鏈表存放在內(nèi)核中并由消息隊列標(biāo)識符標(biāo)識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點。
③信號量:信號量是一個計數(shù)器,可以用來控制多個進(jìn)程對共享資源的訪問。它常作為一種鎖機制,防止某進(jìn)程正在訪問共享資源時,其他進(jìn)程也訪問該資源。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。
④共享內(nèi)存:共享內(nèi)存就是映射一段能被其他進(jìn)程所訪問的內(nèi)存,這段共享內(nèi)存由一個進(jìn)程創(chuàng)建,但多個進(jìn)程都可以訪問。共享內(nèi)存是最快的 IPC 方式,它是針對其他進(jìn)程間通信方式運行效率低而專門設(shè)計的。它往往與其他通信機制,如信號量,配合使用,來實現(xiàn)進(jìn)程間的同步和通信。
⑤SocketSocket 也是一種進(jìn)程間通信機制,與其他通信機制不同的是,它可用于不同及其間的進(jìn)程通信。
下面我們用Swoole中的Process模塊來加深一下對進(jìn)程的理解。在Swoole中通過swoole_process 類來創(chuàng)建子進(jìn)程,構(gòu)造函數(shù)原型如下:
$function 是一個回調(diào)函數(shù),子進(jìn)程創(chuàng)建成功后執(zhí)行此回調(diào)函
$redirect_stdin_stdout 參數(shù)可以重定向子進(jìn)程的標(biāo)準(zhǔn)輸入和輸出
$pipe_type 為管道類型
具體參數(shù)含義可以參考Swoole官方文檔,下面我們將在一個進(jìn)程中創(chuàng)建子進(jìn)程,并進(jìn)行進(jìn)程間通信。
在命令行執(zhí)行 php process.php,運行后的結(jié)果如下:
這就是進(jìn)程之間通過管道通信的例子,創(chuàng)建子進(jìn)程,并設(shè)定回調(diào)函數(shù)。
Event::add 將管道文件描述符 $process->pipe 加入到事件循環(huán)中。第一行輸出的hello world 是回調(diào)函數(shù)輸出的,而 read:aaaaaa 是事件循環(huán)執(zhí)行時從管道里讀出的數(shù)據(jù)。
到此,相信大家對“PHP程序員都應(yīng)該知道的進(jìn)程知識有哪些”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!