<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 進程 ![](http://cdn.aipin100.cn/17-10-9/66029542.jpg) ### 進程是什么? 如果你搜索“什么是進程?”,你大概都會看到這樣的答案:“進程是程序的基本執行實體”,“進程是系統進行資源分配和調度的基本單位”,...等等。 看了后你還是不懂什么是進程,因為這個回答太官方了,除了讓你不明覺厲之外沒有作用。 那為什么進程的概念很難說清楚呢,或者說為什么向人描述清楚“進程是什么?”的這個問題不容易呢。 這要從我們寫的代碼是怎么在計算機中被執行的說起了,并不是像我們想象中的那樣,自上而下,獨占CPU,整體一遍過執行完的,真實的代碼變成指令,再被調度執行很復雜,這里只做一個引子,感興趣的讀者可以自行查閱[相關資料](https://mp.weixin.qq.com/s/Q0SaoTg9GTXwOeh0GmLOuQ)。 代碼的真實執行過程不是我們所想象的那樣,但是程序員喜歡簡單,不想關心底層復雜的具體執行,畢竟寫上層業務功能就已經不容易了。于是操作系統就滿足了程序員這個愿望,滿足的方式就是創建了進程的概念給程序員理解,屏蔽掉其它復雜的概念。 這就是進程。 等等,我好像還沒有說“進程是什么”。 但我想你已經明白了,你會有自己的思考和理解,可能每個人理解都會不一樣,可至少對于這個問題你已經有了自己的思考,不會再只有不明覺厲。 ---- ### 進程的概念 進程:一個具有一定獨立功能的程序關于某個數據集合的一次運行活動,是系統進行資源分配和調度運行的基本單位。 更多的信息需要你自行搜索相關資料以加深理解,詳細講解進程的概念不在本文的范疇內。 php的進程操作需要安裝 [pcntl](http://php.net/manual/zh/book.pcntl.php) 擴展。 [操作系統 - 進程的概念 - 情有獨鐘 - 博客園](https://www.cnblogs.com/tianlangshu/p/5224178.html) [編程這么久你可能沒真正了解進程](https://mp.weixin.qq.com/s/FRwg2WPbYkdnN71dCGPe6w) [高并發的那點事兒](https://mp.weixin.qq.com/s/n9FnQq2K93JTTr1kMkwJaw) ***** ### 多進程 在php中使用 [pcntl_fork](http://php.net/manual/zh/function.pcntl-fork.php) 函數創建進程。 從官方文檔的介紹中,我們總結出`pcntl_fork()`有以下幾點重要的特性: 1. 從當前進程`pcntl_fork()`調用的位置處產生分支(子進程) 2. **父進程和子進程 都從fork的位置開始向下繼續執行**,不同的是父進程執行過程中,得到的fork返回值為子進程的進程id,而子進程得到的是0。 3. 返回值:成功時,在父進程執行線程內返回產生的子進程的PID,在子進程執行線程內返回0。失敗時,在 父進程上下文返回-1,不會創建子進程,并且會引發一個PHP錯誤。**根據返回值我們就知道父進程與子進程的代碼部分。** 4. 子進程僅PID(進程號) 和PPID(父進程號)與其父進程不同。**子進程擁有父進程完整的副本(函數、變量等),而不是共享,進程間相互獨立,互不影響**,每次fork都將**以當前環境產生新的副本。** 5. fork之后,是父進程先執行還是子進程先執行無法確認,準確的說是,**進程的執行順序不受控制,而是取決于系統調度。** 6. **在跳轉分支結構中,子進程可能會出現“往回執行”的情況**,此時應特別注意。通常出現此問題是由于子進程沒有退出的原因造成的。 如果你有過其他語言的多進程編程經驗的話,那么以上理解起來應該很容易,否則的話,你很有可能會輕視了fork調用的原理,下面的例子將幫助和加深你對它的認識。 初探: 一個簡單的多進程例子 ```php <?php // 外面所有的代碼都是父進程的環境 // 可以獲取父進程的ID // 子進程擁有父進程的完整副本,所以此函數自然也被子進程繼承了 function shutdown_function() { global $i; $pid = getmypid(); // 情況2時,這個i一直是4的,待研究…… echo PHP_EOL . "................ process shutdown i:{$i} pid: $pid " . isStartPid() . '......................' . PHP_EOL; sleep(20); } register_shutdown_function('shutdown_function'); $startPid = getmypid(); echo "start parent startPid: {$startPid}" . PHP_EOL; function isStartPid() { global $startPid; if (getmypid() == $startPid) { return ' [is startPid] '; } else { return ' '; } } // 這個for在父進程的環境內 for ($i = 1; $i <= 3; $i++) { // 由于自進程可能會繼續執行for結構的原因(子進程往回執行),所以這里也可能會是子進程的部分 $_pid = getmypid(); // $i=1 時,fork()之前的部分屬于父進程所有($_pid一定為開始父進程pid,此后就不一定了) echo PHP_EOL . PHP_EOL . "=====>>>>>>>>>>==== for i:{$i} pid: $_pid " . isStartPid() . '=====>>>>>>>>>======' . PHP_EOL; $pid = pcntl_fork(); // 父進程fork出來的子進程擁有父進程的副本 // 那么現在就不止父進程的環境了 // 那哪部分是父進程的代碼,哪部分是子進程的代碼呢,通過 $pid 判斷 if ($pid < 0) { exit('fork error'); } // 接下來的代碼,有兩部分,子進程和父進程 // 父進程和子進程將繼續執行fork之后的程序代碼 // fork之后的代碼屬于父進程和子進程共同所有,通過判斷 $pid 分隔開 if ($pid > 0) { // 父進程部分 $parentPid = getmypid(); // $pid 其實是子進程的PID(本次fork()的子進程id) // 這里也可能會出現兒子逆襲成父的進程(子進程“往回”執行時) // 情況1 $parentPid = $startPid ;情況2 不一定 echo PHP_EOL . "i:{$i} 父 parentPid: $parentPid " . isStartPid() . " (子: child_pid: $pid)" . PHP_EOL; } else if (0 == $pid) { $child_pid = getmypid(); // 子進程部分 echo PHP_EOL . " i:{$i} 子 child_pid: $child_pid " . isStartPid() . PHP_EOL; // 這行未注釋時會出現子進程“往回”執行的情況,為情況2,見分析2。注釋時,為情況1,見分析1 exit; } // 判斷外部分屬于父進程和子進程共同所有 // sleep(1); // 但是由于這是for結構,子進程執行到這里后還會繼續執行,所以會繼續執行for結構,這使得子進程“往回”執行了(要知道本來子進程都在fork之后的) // 當為子進程“往回”執行的情況,此時有一些微妙的細節需要注意,此結構會再次執行 pcntl_fork(),注意此時的上下文已經發生變化了 // 此子進程會再次fork一個子進程,而他本身就成為了另一個父進程(兒子逆襲當父) // 父進程更不用說了,繼續執行for結構,父進程都是同一個(沒發生“往回”執行的情況時),為: start parent pid echo PHP_EOL . "=====<<<<<<<<<<<==== for end i:{$i} pid: $_pid " . isStartPid() . '======<<<<<<<<<<<=====' . PHP_EOL . PHP_EOL; } // 這兒就完全是父進程的部分了 // 但這兒真的就一定是父進程才會執行的部分嗎?那個在“往回”執行時逆勢成父的進程呢?它算真正的父進程嗎?會執行到這里嗎? $pid = getmypid(); echo PHP_EOL . "=========== for after i:{$i} pid: {$pid} " . isStartPid() . PHP_EOL; ``` #### 打印分析: **分析1:** print: ```shell start parent startPid: 5955 =====>>>>>>>>>>==== for i:1 pid: 5955 [is startPid] =====>>>>>>>>>====== i:1 父 parentPid: 5955 [is startPid] (子: child_pid: 5956) =====<<<<<<<<<<<==== for end i:1 pid: 5955 [is startPid] ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:2 pid: 5955 [is startPid] =====>>>>>>>>>====== i:1 子 child_pid: 5956 ................ process shutdown i:1 pid: 5956 ...................... i:2 父 parentPid: 5955 [is startPid] (子: child_pid: 5957) =====<<<<<<<<<<<==== for end i:2 pid: 5955 [is startPid] ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:3 pid: 5955 [is startPid] =====>>>>>>>>>====== i:2 子 child_pid: 5957 ................ process shutdown i:2 pid: 5957 ...................... i:3 父 parentPid: 5955 [is startPid] (子: child_pid: 5958) =====<<<<<<<<<<<==== for end i:3 pid: 5955 [is startPid] ======<<<<<<<<<<<===== =========== for after i:4 pid: 5955 [is startPid] ................ process shutdown i:4 pid: 5955 [is startPid] ...................... i:3 子 child_pid: 5958 ................ process shutdown i:3 pid: 5958 ...................... ``` process tree: > 進程執行完畢后就自動退出了,那還怎么再用 `pstree` 命令打印進程樹呢。只有讓每個進程在最后時刻休眠一下,以不讓其馬上退出才行,要實現這個要求,shutdown_function 函數剛好合適,且只需在最初的父進程中定義一次即可,其后所有子進程都將擁有其副本。 ```shell php(5955)─┬─php(5956) ├─php(5957) └─php(5958) ``` ***** **分析2:** print: ```shell start parent startPid: 6063 =====>>>>>>>>>>==== for i:1 pid: 6063 [is startPid] =====>>>>>>>>>====== i:1 父 parentPid: 6063 [is startPid] (子: child_pid: 6064) =====<<<<<<<<<<<==== for end i:1 pid: 6063 [is startPid] ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:2 pid: 6063 [is startPid] =====>>>>>>>>>====== i:1 子 child_pid: 6064 =====<<<<<<<<<<<==== for end i:1 pid: 6063 ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:2 pid: 6064 =====>>>>>>>>>====== i:2 父 parentPid: 6063 [is startPid] (子: child_pid: 6066) =====<<<<<<<<<<<==== for end i:2 pid: 6063 [is startPid] ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:3 pid: 6063 [is startPid] =====>>>>>>>>>====== i:2 父 parentPid: 6064 (子: child_pid: 6065) =====<<<<<<<<<<<==== for end i:2 pid: 6064 ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:3 pid: 6064 =====>>>>>>>>>====== i:3 父 parentPid: 6063 [is startPid] (子: child_pid: 6067) =====<<<<<<<<<<<==== for end i:3 pid: 6063 [is startPid] ======<<<<<<<<<<<===== =========== for after i:4 pid: 6063 [is startPid] ................ process shutdown i:4 pid: 6063 [is startPid] ...................... i:3 子 child_pid: 6067 =====<<<<<<<<<<<==== for end i:3 pid: 6063 ======<<<<<<<<<<<===== =========== for after i:4 pid: 6067 ................ process shutdown i:4 pid: 6067 ...................... i:2 子 child_pid: 6066 =====<<<<<<<<<<<==== for end i:2 pid: 6063 ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:3 pid: 6066 =====>>>>>>>>>====== i:3 子 child_pid: 6069 =====<<<<<<<<<<<==== for end i:3 pid: 6066 ======<<<<<<<<<<<===== i:3 父 parentPid: 6064 (子: child_pid: 6068) =====<<<<<<<<<<<==== for end i:3 pid: 6064 ======<<<<<<<<<<<===== i:2 子 child_pid: 6065 =====<<<<<<<<<<<==== for end i:2 pid: 6064 ======<<<<<<<<<<<===== =====>>>>>>>>>>==== for i:3 pid: 6065 =====>>>>>>>>>====== i:3 子 child_pid: 6068 =====<<<<<<<<<<<==== for end i:3 pid: 6064 ======<<<<<<<<<<<===== =========== for after i:4 pid: 6068 ................ process shutdown i:4 pid: 6068 ...................... =========== for after i:4 pid: 6069 ................ process shutdown i:4 pid: 6069 ...................... i:3 父 parentPid: 6066 (子: child_pid: 6069) =====<<<<<<<<<<<==== for end i:3 pid: 6066 ======<<<<<<<<<<<===== =========== for after i:4 pid: 6066 ................ process shutdown i:4 pid: 6066 ...................... =========== for after i:4 pid: 6064 ................ process shutdown i:4 pid: 6064 ...................... i:3 父 parentPid: 6065 (子: child_pid: 6070) =====<<<<<<<<<<<==== for end i:3 pid: 6065 ======<<<<<<<<<<<===== i:3 子 child_pid: 6070 =====<<<<<<<<<<<==== for end i:3 pid: 6065 ======<<<<<<<<<<<===== =========== for after i:4 pid: 6070 =========== for after i:4 pid: 6065 ................ process shutdown i:4 pid: 6065 ...................... ................ process shutdown i:4 pid: 6070 ...................... ``` process tree: ```shell php(6063)─┬─php(6064)─┬─php(6065)───php(6070) │ └─php(6068) ├─php(6066)───php(6069) └─php(6067) ``` 通過這個打印過程和進程樹分析,大家應該可以清晰地看到進程交錯的執行過程、和退出的時機,以及子進程的執行細節。 如“往回執行”成為父進程再生子,注意每次“往回執行”時所攜帶的當前副本與每次fork的副本的關系,這些微妙的細節造成了這些效果。 原例子在這里:[PHP多進程初探 --- 開篇](https://blog.ti-node.com/blog/6363989547574886401),本文只是針對這個例子進行細節分析,以幫助大家理解。(建議大家先看看,再結合本文的分析,這樣效果會比較好。) 本例雖然沒有深入的演示php多進程的高級特性:進程通信、信號處理等,但是這個簡單的例子卻演示了php多進程的關鍵部分,以及最重要的細節,徹底理解和掌握這些,將為后面的學習掃清障礙。 ***** ### 僵尸進程 ***** ### 孤兒進程 ***** ### 進程通信 ***** ### 實現守護進程daemon ***** ### 實現一個通用的多進程管理模型 目標:實現一個高可用的,通用的多進程管理模型,可在多種業務模式下靈活使用。 ***** ### 參考 >[danger] 由于每段代碼執行邏輯不同,所處環境也不同,所以出錯的幾率也不同,**一般主進程存在較小的崩潰概率,因為它邏輯直觀,不會摻雜任何的業務邏輯代碼,所以幾乎不會出錯中斷(甚至設計中可以認為此部分不會出錯,負載均衡部分也同理)**,但是worker進程就不同了,它是業務邏輯的具體執行部分,這里出錯是不可預料的,所以對于這部分代碼,可以理解為一定會出錯,主進程應做好維護工作。 [PHP多進程處理并行處理任務實例](https://www.toutiao.com/a6603186787361751555/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1538717346&app=news_article_lite&utm_source=weixin&iid=33124962994&utm_medium=toutiao_android&group_id=6603186787361751555) [php多進程通信,有名管道(pcntl學習)](https://www.toutiao.com/a6483811732593574413/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1538709568&app=news_article_lite&utm_source=weixin&iid=33124962994&utm_medium=toutiao_android&group_id=6483811732593574413) [在 Linux 中安全且輕松地管理 Cron 定時任務](https://www.toutiao.com/a6608656518864699912/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1538709040&app=news_article_lite&utm_source=weixin&iid=33124962994&utm_medium=toutiao_android&group_id=6608656518864699912) [naruto | An object-oriented multi process manager for PHP :robot:](http://naruto.tigerb.cn/docs/specification-zh.html) > 在我們實際的業務場景中(PHP技術棧),我們可能需要定時或者近乎實時的執行一些業務邏輯,簡單的我們可以使用unix系統自帶的crontab實現定時任務,但是對于一些實時性要求比較高的業務就不適用了,所以我們就需要一個常駐內存的任務管理工具,為了保證實時性,**一方面我們讓它一直執行任務(適當的睡眠,保證cpu不被100%占用),另一方面我們實現多進程保證并發的執行任務。** [PHP多進程-半城煙沙-51CTO博客](http://blog.51cto.com/vabc1314/1854640) > 實際過程中,肯定不能使用sleep()函數不讓master進程退出的,需要使用pcntl_wait($status,WUNTRACED);來等待子進程的信號。(睡眠是一種低效率的阻塞,pcntl_wait才是標準的阻塞IO模型) > > ……關閉文件描述符。同文件權限掩碼一樣,用fork()函數新建的子進程會從父進程那里繼承一些已經打開的文件。這些被打開的文件可能永遠不會被守護進程讀或寫,但它們一樣消耗系統資源,而且可能導致所在的文件系統無法被卸載。…… [PHP多進程系列筆記(五) - 飛鴻影下 - SegmentFault 思否](https://segmentfault.com/a/1190000015390057?utm_source=tag-newest) [守護進程之PHP實現 - 假裝是個程序員 - SegmentFault 思否](https://segmentfault.com/a/1190000008916867) [php:多進程執行任務 - php:從入門到頸椎康復 - SegmentFault 思否](https://segmentfault.com/a/1190000015482154?utm_source=tag-newest) [進程控制(2): 進程操作 - XiaoManon - 博客園](https://www.cnblogs.com/xiaomanon/p/4201006.html) > 由于創建的新進程和父進程在系統看來是地位平等的兩個進程,所以運行機會也是一樣的,我們不能夠對其執行先后順序進行假設,先執行哪一個進程取決于系統的調度算法。如果想要指定運行的順序,則需要執行額外的操作。正因為如此,程序在運行時并不能保證輸出順序和上面所描述的一致。 [基于swoole擴展實現真正的PHP數據庫連接池 - 圓旭 - 博客園](https://www.cnblogs.com/pinganzi/p/6640507.html) > PHP的數據庫連接池一直以來都是一個難題,很多從PHP語言轉向Java的項目,大多數原因都是因為Java有更好的連接池實現。**PHP的MySQL擴展提供了長連接的API,但在PHP機器數量較多,規模較大的情況下,mysql_pconnect非但不能節約MySQL資源,反而會加劇數據庫的負荷。** [PHP連接池實現的一種想法 - frf12的博客 - CSDN博客](https://blog.csdn.net/frf12/article/details/54666762) > 在想JAVA可以實現連接池,那么PHP呢?我們用PHP做WEB開發,他們是不常駐內存的,連接池要放在哪,又以何種方式去獲取鏈接呢。 > 利用php的多進程模型去實現一個數據庫連接池。 > 我的想法是用先在服務器上開啟一個PHP守護進程,這個守護進程打開并維護多個鏈接對象,起著連接池的作用,然后每一次數據庫的訪問都由這個守護進程發起,這是進程間通訊,具體使用管道還是網絡都可以,只要把SQL語句傳給守護進程,守護進程啟動一個閑置的連接去執行這條SQL,并將放回結果以進程間通信的方式返回。 (注意:不是把連接池對象直接傳遞給業務進程使用(也沒法傳遞,進程通信,對象傳遞?),而是 守護進程充當代理的角色,所有sql業務交給它執行,類似rpc調用了,但這樣性能能夠提升嗎,能提升多少呢) [關于php的一篇文章《php 應該使用緩存和連接池》_數據庫_Tangxy723的專欄-CSDN博客](https://blog.csdn.net/tangxy723/article/details/8607167) ***** [swoole的進程模型](https://blog.ti-node.com/blog/6379580337835474944) > 很多phper一直停留在php web開發的mvc CURD中,也聽到很多人對自己陷入這種困境中多有不滿,但又不知道如何提高自己,擺脫困境。活脫脫就像一直趴在玻璃上的蒼蠅,前途一片光明,就是飛不出去,可悲可嘆。 話說回來,實際上做到一名合格的CURDer也并不是一件容易的事情,萬萬不可眼高手低。 [swoole的協程是個什么鬼](https://blog.ti-node.com/blog/6411537544197963777) > 實際上你可以這么理解,就是master進程可以hold住上萬個TCP連接是沒有任何問題的,因為master進程內部異步非阻塞的,但是僅僅hold住上萬個TCP連接本身是沒有任何意義的,因為有數據傳輸的TCP連接才是有意義的。一旦有數據傳輸就意味著有業務邏輯產生了,那么master進程并不負責具體業務邏輯代碼了,處理這個業務邏輯的活兒交給worker進程來干,然后干完后再由master進程返回給客戶端。 [老舊話題:yield是個什么玩意(上)](https://blog.ti-node.com/blog/6426271125306605568) > 這是個bug,這是個php的bug,至少我正在使用的PHP 7.1.17版本是有這個bug的,你不要以為這里面有什么高深莫測的技術,就是bug而已。(php卻是有一些這樣的已知和未知BUG,這是無可避免的,畢竟php本身也是一個軟件) [PHP多進程初探 --- 開篇](https://blog.ti-node.com/blog/6363989547574886401) > 由于多進程在apache或者fpm環境下無法正常運行,所以大家一定要在php cli環境下執行下面php代碼。 > > fpm與多進程的PHP結合情況變復雜了,所以保險起見還是只在cli下使用PHP的多進程 > > 每個動態請求都是由 php-fpm 進程fork出來一個子進程來處理(執行我們的代碼部分),此時子進程再fork進程,做多進程管理,就不太好了,畢竟這不是php-fpm的主職,并且由于多進程的復雜性,資源難以管理,如果用不好還可能使進程崩潰,顯然這些給 php-fpm 進程加重了負擔,會影響系統的并發能力,所以只能在CLI下使用多進程。(這就像是讓廚師去做迎賓,結果是只會雞飛蛋打,賠了夫人又折兵) > > 這里說子進程擁有父進程數據空間以及堆、棧的副本,實際上,在大多數的實現中也并不是真正的完全副本。更多是采用了COW(Copy On Write)即**寫時復制**的技術來節約存儲空間。簡單來說,如果父進程和子進程都不修改這些 數據、堆、棧 的話,那么父進程和子進程則是暫時共享同一份 數據、堆、棧。只有當父進程或者子進程試圖對 數據、堆、棧 進行修改的時候,才會產生復制操作,這就叫做寫時復制。 [PHP多進程初探 --- 孤兒和僵尸](https://blog.ti-node.com/blog/6375380006637404161) > 1. 父進程不能先退出,否則子進程就成孤兒進程了。 > 2. 父進程除了不能先退出外,還要善后,即調用`wait`或者`waitpid`等函數對子進程的相關資源(使用過的變量、打開的文件描述符等等)進行清理。 > > 所以問題就在于,父進程如何保持不退出以等待子進程了? > 有兩種方案:1. 父進程中使用wait阻塞等待子進程退出;2. 父進程中安裝信號處理監聽器,監聽子進程的退出信號。 [PHP多進程初探 --- 信號](https://blog.ti-node.com/blog/6375675957193211905) > 子進程在退出的時候,會向父進程發送一個信號,叫做SIGCHLD,那么父進程一旦收到了這個信號,就可以作出相應的回收動作,也就是執行pcntl_waitpid(),從而解決掉僵尸進程 [php進程daemon化的正確做法](https://blog.ti-node.com/blog/6343348095782223873) > 其次是代碼中如果有echo或者print_r之類的輸出文本 , 會被輸出到當前的終端窗口中(進程綁定的輸出終端) [PHP多進程初探 --- 再次談daemon進程](https://blog.ti-node.com/blog/6379889763461103616) > 一些重要的概念:1. 進程組;2. 會話;3. 控制終端 [PHP多進程初探 --- 利用多進程開發點兒東西吧](https://blog.ti-node.com/blog/6379968168328167424) [PHP多進程初探 --- 進程間通信二三事](https://blog.ti-node.com/blog/6379989346195341312) > 往往開啟多進程的目的是為了一起干活加速效率,前面說了不同進程之間的內存空間都是相互隔離的,也就說進程A是無法讀或寫進程B中的任何數據內容的,反之亦然。但是,有些時候,多個進程之間必須要有相互通知的機制,用職場上的話來說就叫“及時溝通”。大家都在一起做同一件事情的不同部分,彼此之間“及時溝通”是很重要的。 > 確切說,如果不用sem的話,上述的運行結果在一定概率下就會產生1而不是2。但是只要加入sem,那就一定保證100%是2,絕對不會出現其他數值。 [kill命令_Linux kill 命令用法詳解:刪除執行中的程序或工作](http://man.linuxde.net/kill) [極客漫畫:不要使用 SIGKILL 的原因(看哭了)](https://www.toutiao.com/a6454826726273843726/?tt_from=weixin&app=news_article&iid=12619555732&wxshare_count=1) [The Smallest Bash Script in the Universe](https://blog.twentytwotabs.com/the-smallest-bash-program-in-the-universe/) shell 腳本是如何執行的,以及為何以 `#!` 開頭 [進程與線程的一個簡單解釋](https://mp.weixin.qq.com/s/COg7NwSJzrLqw7qIWtOK8A) [神奇的ThreadLocal](https://mp.weixin.qq.com/s/5aRRcsua9CF3oeqRbXDb9g) [高性能線程間消息傳遞庫Disruptor概述](https://mp.weixin.qq.com/s/fmqF4qeE7Nr7c1hVAuKROA) [通過 Node.js 的 Cluster 模塊源碼,深入 PM2 原理](https://mp.weixin.qq.com/s/668R5YheK0GGd8kUGtRFVA) [深入理解Node.js 進程與線程(8000長文徹底搞懂)](https://mp.weixin.qq.com/s/N6Omr5HwSPl6JjE2ultoVg) [深入理解計算機系統:進程](https://mp.weixin.qq.com/s/z6K8C56FnNVKu6XAQefViQ) [騷操作 | 不重啟 JVM,替換掉已經加載的類,偷天換日?](https://mp.weixin.qq.com/s/zJaTr5SL-fPLXd9UprTQ0Q) ~~~ 計算機應該是人類有史以來最偉大的發明之一,從電磁感應磁生電,到高低電壓模擬0和1的比特,再到二進制表示出幾種基本類型,再到基本類型表示出無窮的對象,最后無窮的對象組合交互模擬現實生活乃至整個宇宙。 兩千五百年前,《道德經》有言:“道生一,一生二,二生三,三生萬物。” 兩千五百年后,計算機的發展過程也大抵如此吧。 ~~~ [用了這么久的數據庫連接池,你知道原理嗎?](https://mp.weixin.qq.com/s/UPerKMFtUaCR3ozva9UHug) [小白科普:虛擬化簡史](https://mp.weixin.qq.com/s/KVOBKVmkm-Ogvcne3_Xxog) [Java線程為何沒有Running狀態?我猜你不知道。](https://mp.weixin.qq.com/s/w7ZkGq4rAHe4OlOSxyuoWw) > 某種意義上,這也是控制反轉(IoC)機制的一種體現,cpu不用反復去詢問硬盤,這也是所謂的“好萊塢原則”—Don’t call us, we will call you.好萊塢的經紀人經常對演員們說:“別打電話給我,(有戲時)我們會打電話給你。” [計算機內存管理介紹](https://mp.weixin.qq.com/s/n_adWFPgW5LJiEepADueOQ) [SpringCloud微服務如何優雅停機及源碼分析](https://mp.weixin.qq.com/s/3xTwdXCeR_7zepBOI8vZBw) [Java 中幾種常用的 RPC 框架介紹](https://mp.weixin.qq.com/s/hPIQwXR4ZtxgTMwieDSD6A) [揭開 asyncio 的神秘面紗 :從 hello world 說起](https://mp.weixin.qq.com/s/ltORoBfRowAR8iXYD3NDQw) > asyncio 是用來編寫并發程序的庫。在爬蟲、客戶端應用等開發場景中, 我們經常會需要將多個網絡請求并行化來提高程序性能,而 asyncio 框架正好可以很方便的幫助我們實現這個需求。 [LINUX PID 1 和 SYSTEMD - coolshell](https://coolshell.cn/articles/17998.html) [前端進擊的巨人(1):執行上下文與執行棧,變量對象](https://mp.weixin.qq.com/s/lAvyjfBZvX0E50QiW3aW7w) [KA,連接池居然這么簡單?](https://mp.weixin.qq.com/s/y8GEAY0R5YXEZZ3erCZJ4A) [揭開進程、線程、綠色線程的神秘面紗](https://mp.weixin.qq.com/s/uTd86WsHQZJSnll5Plt_4w) [Redis是單線程的,但Redis為什么這么快?](https://mp.weixin.qq.com/s/v70ElApJbgoD8_0A494VIg) [編程中的棧指的是什么?](https://mp.weixin.qq.com/s/7zAJwCrwUcrROFWmypDvbQ) > IIFE模式:匿名函數自調用(閉包 > stack的第一種含義是一組數據的存放方式,特點為LIFO,即后進先出(Last in, first out)。 [什么是線程安全,你真的了解嗎?](https://mp.weixin.qq.com/s/Er5LfxFiCUrbByPjdJ4DNg) [一文看懂線程的生命周期,利用線程池模擬群發短信](https://mp.weixin.qq.com/s/gCnvvpavRPmhDMD6d65KIg) > 線程池,讓線程阻塞,循環沒事的 > 傳統不阻塞的話,執行完畢后就結束生命周期了,所以要不想結束,就只有阻塞掛起了。 > 壓榨,忙碌起來 [編程這么久你可能沒真正了解進程](https://mp.weixin.qq.com/s/FRwg2WPbYkdnN71dCGPe6w) [一個想休息的線程:JVM到底是怎么處理鎖的?怎么不讓我阻塞呢?](https://mp.weixin.qq.com/s/sIMowR_qjskg-WeriMiIlg) [偽共享和緩存行填充,Java并發編程還能這么優化!](https://mp.weixin.qq.com/s/S_x39EB3nPx6oCB9Jy0EZA) [為什么Goroutine能有上百萬個,Java線程卻只能有上千個?](https://m.toutiaocdn.com/group/6577255545676235272/?iid=33124962994&app=news_article_lite&timestamp=1532459481&wxshare_count=1&tt_from=weixin&utm_source=weixin&utm_medium=toutiao_android&utm_campaign=client_share) [ThreadLocal父子線程數據傳遞方案](https://mp.weixin.qq.com/s/D9ZOGqmW17l8p8U5cvn0Rw) > 不能依賴于外部 [一個故事講完進程、線程和協程](https://mp.weixin.qq.com/s/zuWRx1FGuBC-_HwuA7jK3w) [ThreadLocal父子線程數據傳遞方案(修正篇)](https://mp.weixin.qq.com/s/wkryihr9tuCuyqakikC4GQ) [內存那些事](http://toutiao.com/group/6552369670400246280/?iid=31395168747&app=news_article_lite&timestamp=1525642790&wxshare_count=1&tt_from=weixin&utm_source=weixin&utm_medium=toutiao_android&utm_campaign=client_share) [一個故事講完進程、線程和協程](https://mp.weixin.qq.com/s/zuWRx1FGuBC-_HwuA7jK3w) [【底層原理】用戶進程緩沖區和內核緩沖區](https://mp.weixin.qq.com/s/W8GGupa6FuizbWU9CJ5B_Q) > 計時器:計算機能計時是因為晶體振蕩器產生的電磁脈沖。那么所有的定時任務都是以它為基礎的。 [線程安全與線程不安全的區別](http://toutiao.com/group/6553138195117113870/?iid=31395168747&app=news_article_lite&timestamp=1525794589&wxshare_count=1&tt_from=weixin&utm_source=weixin&utm_medium=toutiao_android&utm_campaign=client_share) > 可見性和有序性 > 多個線程執行時,CPU對線程的調度是隨機的,我們不知道當前程序被執行到哪步就切換到了下一個線程 [談談Java中常見的線程安全模型](https://mp.weixin.qq.com/s/_DixMb-gay67XGy_8vb8Kg) [【底層原理】用戶進程緩沖區和內核緩沖區](https://mp.weixin.qq.com/s/W8GGupa6FuizbWU9CJ5B_Q) [進程與線程的一個簡單解釋](https://mp.weixin.qq.com/s/COg7NwSJzrLqw7qIWtOK8A) [那些煩人的同步和互斥問題](https://mp.weixin.qq.com/s/KSCaMjuGX_9FxAq2kFLprg) [C老頭和Java小子的硬盤夜話](https://mp.weixin.qq.com/s/ugw8s8YsYjuxjdfMJBKjZw) [【C++札記】C++11并發編程(一)開啟線程之旅](https://mp.weixin.qq.com/s/DypfPCogpsvcYRodXqjalQ) [關于PHP協程與阻塞的思考](https://mp.weixin.qq.com/s/WxcP_ghWyY3kWoPi_8dC8w) [Node.js : 我只需要一個店小二](https://mp.weixin.qq.com/s/BzrAacmJZEFRXE3vijCVQQ) [我是一個線程(修訂版)](https://mp.weixin.qq.com/s/-BMCUuIWYE3O_oC3ZNNJRg) [Go 為什么這么“快”](https://mp.weixin.qq.com/s/ihJFa5Wir4ohhZUXVSBvMQ) [Asynchronous programming. Blocking I/O and non-blocking I/O](https://luminousmen.com/post/asynchronous-programming-blocking-and-non-blocking) > 一組系列文章,從操作系統的高度,較為通俗地介紹如何認識異步編程。 > 異步的本質,底層實現原理 [你能搞懂connectTimeout和socketTimeout的區別么?](https://mp.weixin.qq.com/s/WYIoGvELo4pFUtkHtQpzGg) [資深程序員總結:分析Linux進程的6個方法,我全都告訴你](https://mp.weixin.qq.com/s/ybDvZcg8oeoQ-6wKXYY8ng) [面試官:兄弟,談談你對分布式系統原理的理解](https://mp.weixin.qq.com/s/vY_NV1_tcTOvVs8RPMb_vg) [ZooKeeper 源碼和實踐揭秘](https://mp.weixin.qq.com/s/DigeE4YxuT55cSeyb1q1tQ) [漫畫:什么是Linux管道](https://mp.weixin.qq.com/s/aXRk85tezwi8xUr_xBy3xg) [我是一個函數](https://mp.weixin.qq.com/s/khV64qj0LhitngVrRBiLug) [操作系統是個大騙子?](https://mp.weixin.qq.com/s/F_rGON3DCwyrWi4V9Vj6uQ) [圖解 | 線程的麻煩事兒,Actor能解決嗎?](https://mp.weixin.qq.com/s/31Pj6-wrMx8kjYoSy_b7FA) > 說說我的看法,其實關于并發競爭,總體就兩類方案: 一種是保守派,一種是僥幸派。 保守派的做法是把所有操作串行化,采用的方法如悲觀鎖、操作隊列等。 僥幸派的做法是碰碰運氣,成功了說明運氣好,不成功繼續碰碰運氣,采用的方法如樂觀鎖、版本號、CAS等,其實原理都一樣。 其次是關于事務,無論是本地的還是分布式的,都無法100%得到保證。事務的關鍵點是在失敗時會自動回滾,但是回滾可靠嗎? 嚴格來說任務事情都無法100%可靠,我們要做的是盡量讓其可靠以及準備一些補償方案,記錄一些關鍵數據信息,實在不行,最后人肉恢復或調整。 [程序員精進之路:性能調優利器--火焰圖](https://mp.weixin.qq.com/s/GFPMIJGT4x6Q_86ZZfOOpg) [就為了一個原子操作,其他CPU核心罷工了](https://mp.weixin.qq.com/s/jx0EajGXGrM3fR14P9Bm7Q) [內核地址空間大冒險4:線程切換](https://mp.weixin.qq.com/s/dpzB7k1kdkClohRWA-ludQ) [兩個程序悲催的進化旅程](https://mp.weixin.qq.com/s/9EUsVWhEr8sMrqZES2ziww) [數據庫鏈接池終于搞對了,直接從100ms到3ms](https://mp.weixin.qq.com/s/ZdDpgXnjStRoZIlh-3iRsg) [困難人生之CLang的wait以及waitpid](https://t.ti-node.com/thread/6472490733105315841) [你不知道的 WeakMap](https://mp.weixin.qq.com/s/iacn5m0qjaAPS2huG2pKRA) [什么時候不要使用微服務?以Istio為例](https://mp.weixin.qq.com/s/doJcgfcymTaPNDEUA-tXVQ) [萬級K8s集群背后etcd穩定性及性能優化實踐](https://mp.weixin.qq.com/s/SZgSbWwKNZTVJOZ_pKLblA) [淺談RPC那些事兒\[1\]](https://mp.weixin.qq.com/s/EZV_fdFB8feTuDe-riqN6A) [超詳細!微服務RPC框架內核解析!](https://appzcodh6sz4402.h5.xiaoeknow.com/v1/course/alive/l_5f22d519e4b0dc56a6d0c802?access_entry=1&app_id=appZCodH6sz4402&entry=2&entry_type=2001&func_type=1&scene=%E5%88%86%E4%BA%AB&share_type=100&share_user_id=u_5ef724179afd1_MxRvMamspI&type=2&available=true&is_redirect=1) > 保存上下文,上下文是什么,其實就是當前的進程,只要frck一下,讓這個進程保持就可以了。 > 異步處理可以提高服務的吞吐能力,因為服務能快速響應,不需要等待執行結果,而工人進程會不斷消費任務,哪怕在沒有請求時可能也還在工作,所以cpu的利用幾乎是飽和效率的,而同步處理經常完成瞬時壓力大,大量io集中在一時間段,導致整體響應都很慢,過后cpu反而被閑置了。 [操作系統和并發的愛恨糾葛](https://mp.weixin.qq.com/s/v0xLt69qOEkIiLJlSaHxEw) [Shell:管道與重定向](https://mp.weixin.qq.com/s/zqt8j4Ag0cTYJgb5E30x1A) ***** last update:2018-10-18 17:07:15
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看