首页
/
每日頭條
/
圖文
/
drools從入門到精通
drools從入門到精通
更新时间:2025-06-01 22:49:20

應評論要求,今天發一篇swoole的文章。如果感覺有幫助,記得點個贊,轉發分享評論。

進程隔離

官網上有那麼一句話:

進程隔離也是很多新手經常遇到的問題。修改了全局變量的值,為什麼不生效,原因就是全局變量在不同的進程,内存空間是隔離的,所以無效。

如果小夥伴們之前對進程沒有概念,要理解起來還是有一定難度的。所以在這裡,我有必要說一下進程是什麼東西。

簡單來說,進程是一個數據結構,數據結構裡面存放了很多成員變量,這個是最本質的。很多書說:

進程是資源的集合

那麼這句話所說的資源指的就是這些變量存放的東西,集合指的就是進程這個數據結構。

如果還是有一些抽象,不要緊,我們去看看Linux中進程這個數據結構的定義是怎樣的。數據結構的定義在這裡,大概是在593行的位置:

我列舉幾個這個數據結構裡面我們聽的比較多的成員變量:

struct task_struct {

操作系統會為每一個進程分配一個task_struct數據結構,一旦CPU執行某個進程的代碼的時候,操作系統把當前進程的這些變量提供給CPU。因為每個進程都有自己的這個task_struct數據結構,所以每個進程的變量是在各自的進程裡面的,因此不同進程的變量是隔離的,這些變量也包括全局變量、文件句柄(即上圖中的fd)。

緊接着,官網又給出那麼一句話:

不同進程的文件句柄是隔離的,所以在A進程創建的Socket連接或打開的文件,在B進程内是無效,即使是将它的fd發送到B進程也是不可用的

這句話什麼意思呢?為了搞清楚,我們要知道文件句柄的作用。

當用戶調用open系統調用(或者其他打開文件的系統調用)的時候,内核會創建一個打開文件對象來表示該文件的一個打開實例。内核同時也會分配一個文件描述符(也就是上圖中的fd)作為打開文件對象的句柄。如下圖所示:

drools從入門到精通(看了這篇文章你就懂了)1

open系統調用向進程返回這個文件描述符,然後這個文件描述符就被存放在file array裡面了。然後進程就可以通過這個fd1來找到對應的文件。那麼,圖中的offset是什麼意思呢(我們把offset叫做打開文件對象)?在Unix系統中,文件默認是順序訪問的。當用戶打開文件的時候,内核初始化這個offset的偏移指針為0。舉個例子,如果當前進程剛打開一個文件(文件内容是字符串abcdefghijklnm),那麼此時offset的狀态如下:

drools從入門到精通(看了這篇文章你就懂了)2

因為offset的偏移指針為0,所以指向字母a。所以,當我們通過fd去讀取文件内容的時候,讀取到的第一個字符就是字母a。假設我連續讀了3個字節,那麼此時的狀态應該是這個樣子的:

drools從入門到精通(看了這篇文章你就懂了)3

也就是說,當進程從文件裡面讀取3個字節之後,offset此時指向字母d。當進程下一次讀取文件的時候,讀取出來的第一個字母就是d了。這就是offset的概念。

同一個進程還可以多次打開同一個文件,如下圖所示:

drools從入門到精通(看了這篇文章你就懂了)4

可以看出,雖然fd1和fd2都是指向同一個文件,但是,如果進程通過fd1去讀取文件的話,讀到的第一個字母是d;如果進程通過fd2去讀取文件的話,讀取到的第一個字母是a。所以,每個文件描述符代表着與文件的一個獨立會話,對應的打開文件對象(即圖中的offset)保存者該會話的内容,這包括了被打開文件的模式(隻讀、隻寫、讀寫)以及下一次讀取或者寫入時的偏移指針。

我們通過代碼來直觀感受一下:

$handle1 = fopen("file.txt", "r");

$handle2 = fopen("file.txt", "r");

$content = fread ($handle1 , 3);

echo "The process reads three bytes through handle1, the content is: " . $content . PHP_EOL;

$content1 = fread ($handle1 , 1);

$content2 = fread ($handle2 , 1);

echo "The process reads one bytes through handle1, the content is: " . $content1 . PHP_EOL;

echo "The process reads one bytes through handle2, the content is: " . $content2 . PHP_EOL;

結果如下:

drools從入門到精通(看了這篇文章你就懂了)5

驗證了我們的說法。

正是因為offset這個打開文件對象對同一個文件的不同會話進行了隔離,所以,才有了官網的這句話:

不同進程的文件句柄是隔離的,所以在A進程創建的Socket連接或打開的文件,在B進程内是無效,即使是将它的fd發送到B進程也是不可用的

也就是說,就算fd是一樣的,但是offset是不一樣的。

其實到這裡算是講完了隔離,但是,我還想再講一點其他的東西。

即,同一個進程是否可以讓多個fd指向同一個offset,從而達到多個fd共享同一個offset的效果呢?答案是可以做到。

進程可以通過dup系統調用來複制一個文件描述符fd,這樣一來,兩個文件描述符共享着相同的會話:

drools從入門到精通(看了這篇文章你就懂了)6

代碼如下:

$handle1 = fopen("file.txt", "r");

$handle2 = dup($handle1);

$content = fread ($handle1 , 3);

echo "The process reads three bytes through handle1, the content is: " . $content . PHP_EOL;

$content1 = fread ($handle1 , 1);

$content2 = fread ($handle2 , 1);

echo "The process reads one bytes through handle1, the content is: " . $content1 . PHP_EOL;

echo "The process reads one bytes through handle2, the content is: " . $content2 . PHP_EOL;

(注意,這段代碼運行不了,因為PHP沒有提供dup這個函數)

假設,這個函數是可以運行,那麼輸出的結果應該是

The process reads three bytes through handle1, the content is: abc

The process reads one bytes through handle1, the content is: d

The process reads one bytes through handle2, the content is: e

drools從入門到精通(看了這篇文章你就懂了)7

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
真假燕窩怎麼分辨
真假燕窩怎麼分辨
燕窩一直都有“稀世名藥”、“東方珍品”的美稱,位居“山珍海味”八珍之首。它不僅能滋陰潤肺、美容養顔,還能提高免疫力,延緩衰老。所以,曆來都是朝廷的貢品。如今,燕窩飛進尋常百姓家,很多女性和孕婦都把它作為滋補養生的首選。雖然養生功效有目共睹,...
2025-06-01
建行龍支付怎麼更新
建行龍支付怎麼更新
經曆了過去十年的各自為政、遍地開花,銀行App走到了從分到合的曆史轉折點,集中化的趨勢不斷凸顯。作者:董雲峰編輯:葉冬上線5年的建行龍支付App沒了。意料之中的事,近年來銀行App的下線并不鮮見。這不代表收縮,恰恰相反,銀行對App的投入力...
2025-06-01
打發時間有哪些方式
打發時間有哪些方式
打發時間的100種方式,無聊的時候可以來試試​​​。,
2025-06-01
120平方雙陽台戶型設計
120平方雙陽台戶型設計
陽台,建築室内空間的延伸。作為室内空間與大自然無界交互的場所,隻有一個陽台的房子晾衣、觀景隻能在一個地方,而雙陽台一個居家實用,一個緻敬夢想。生活陽台和景觀陽台分開。在生活陽台,可安全放置燃氣熱水器,避免放于室内,規避煤氣洩漏風險,多了一個...
2025-06-01
上海多少家商超
上海多少家商超
11日起,上海全市按照封控區、管控區、防範區三類實施分區分級差異化防控管理。根據相關政策,在封控區和管控區,商業網點“關門不停業”,在防範區,有限允許商業網點恢複經營。記者采訪發現,一些商超等民生類商業網點開始恢複運營。“目前,上海超市賣場...
2025-06-01
Copyright 2023-2025 - www.tftnews.com All Rights Reserved