## 定時-時鐘-阻塞
定時執行,具體實現有兩種形勢,一種是類似于linux的計劃任務,每隔一定時間去執行什么腳本任務,另一種是,比如,在php腳本里面做無限循環,每次循環睡眠多少時間,這個時間就是間隔。這兩種方式表面上看似差不多,但有一個重要的細節,那就是第一種,如果任務很耗時,也不會阻塞計劃任務,也就是說,如果任務耗時,任務需要兩秒鐘執行玩,計劃任務間隔是一秒鐘,那么可能會出現,有兩個任務同時在執行的情況,這是如果涉及到資源搶奪和并發問題就需要考慮了。而第二種由于是靠循環來做定時的,所以任務執行過程中會阻塞定時,所以不會出現兩個任務同時在執行。總之各有特點,在實際問題時,請謹慎考慮實際情況,在做決定,不要忽視掉這個重要的細節,性能和安全,首選安全,其次再考慮優化性能。
* * * * *
### 定時器程序是否受任務的阻塞
其實,問題的本質就是,定時器程序是否受任務的阻塞。比如linux的計劃任務,肯定是有一個定時器,每隔一分鐘讀取計劃任務配置,然后執行相應的任務,但是這個任務就是個命令行任務,定時器可能是利用某種方式執行它,無論這個命令行是做什么,它并不會阻塞定時器的下一分鐘。所以定時器會無視所有東西,定時器永遠按照它的循環方式,一分鐘,又一分鐘,沒人能打擾。也就是說,它有一個承諾,那就是我能確定我沒隔一分鐘都會回來,它能履行這個承諾。而第二種方式雖然也是這樣說,但是實際上它并不能履行承諾。這里關鍵一點,linux到底是怎么做到任務命令行不阻塞定時器的:
- php里面的幾個可以直接執行系統命令的函數,能不能做到這樣,不阻塞當前運行,有待實驗,如果能做到,那么也能像linux計劃任務那樣了。
- 還有swool的定時器,會不會被里面的任務阻塞,也有待實驗。
- 還有php腳本中使用命令行函數,執行的進程,和當前腳本是什么關系,如果當前腳本死了,會影響由它產生的進程嗎,待實驗。
- 還有以前v1版本的,常駐服務,啟動時的幾個腳本,待重新研究一下。
參考:
[JAVA互聯網架構-同步、異步、阻塞和非阻塞區別](http://www.toutiao.com/a6464076225433305613/?tt_from=weixin&utm_campaign=client_share&app=news_article&utm_source=weixin&iid=12619555732&utm_medium=toutiao_android&wxshare_count=1)
[PHP中如何執行shell命令-CSDN論壇](http://bbs.csdn.net/topics/390847194)
[PHP 調用shell命令 - 墨言莫問 - 博客園](http://www.cnblogs.com/daochong/p/7084729.html)
[php里調用shell命令【轉】 - 午后的貓 - 博客園](http://www.cnblogs.com/Dreama/articles/3381380.html)
[php非阻塞訪問url 解析socket阻塞與非阻塞,同步與異步 - 橙虛緣空間 - CSDN博客](http://blog.csdn.net/qq43599939/article/details/50570098)
* * * * *
### 定時器并發處理多任務(效率)
上面還漏掉一個細節,如果linux定時器,從配置讀出來當前有好幾個任務要執行,如果循環一個個執行會不會效率低,所以它可能這樣,多個就創建多個子進程或線程去做這些事就快了,其實這就是多消息處理阻塞優化問題,比如如果用mysql我們讀出來,多條任務消息待處理,如果使用循環,那么后面的任務要被前面的執行過程阻塞。效率就低,此時php腳本開多進程,就能明顯加快任務的處理速度了。
> 任務間阻塞,可以開多進程執行解決。否則單純的類似于事件循環方式的異步也沒什么用,因為把任務堆積在事件隊列里面也并沒有從根本上解決問題從而加快任務的處理。
* * * * *
### 終究是一場模仿游戲
cpu就像是電腦的心臟,人的心臟在不停的跳動,并且有相對穩定的跳動頻率,只要人活著,心臟就會跳動,以產生壓力,讓血液流動,代謝和運輸氧氣。這是生命的保證。心臟就像是一個定時器,每隔一個時間跳動一次,像個無限循環。所以對于電腦的心臟cpu也是這樣,它的跳動就是時鐘震蕩。沒想到很多東西本質都是相似的,這終究是一場模仿游戲,我們并沒有創造出什么,我們只是一直在玩模仿游戲。
心臟就像cpu的震蕩頻率,有心跳頻率,劇烈運動時心跳極速加快,恢復平靜坐著時心跳減慢恢復正常。可見萬物的規律都是一樣。生命是最高級的科技。無論我們科技在高級,只能模仿,卻不能憑空創造生命。(我認為克隆和利用現有材料/細胞合成的生命體不能算作是創造生命)
所以無論何時都要敬畏生命。
> 但也不能完全將cpu和心臟類比。對人體來說,心臟是提供血液循環動力的,將血液運送到全身,而思考的地方是大腦神經。cpu時鐘頻率的特點和心臟有類似,但是cpu更像是人的大腦。其實cpu本身沒有思維能力,它只有簡單的指令,應該說編程賦予了cpu像大腦一樣的處理能力。不論怎么對比,總會太牽強,計算機不是仿生學,計算機的誕生是為了簡化繁雜的計算,解放人力的。所以可以把計算機當作機械對待。不要完全將它和人對比。(汽車的發動機更像是電腦的電源而不是cpu,汽車上的中央控制器才是cpu)
[在一個時鐘周期內,cpu僅完成一個最基本的動作,這個最基本的動作是什么動作?-超能網的回答-悟空問答](https://www.wukong.com/answer/6492978840963383565/?iid=12619555732&app=news_article&share_ansid=6492978840963383565&wxshare_count=1&tt_from=weixin&utm_source=weixin&utm_medium=toutiao_android&utm_campaign=client_share)
TODO: 了解 在《我的世界》中建造模擬cpu是怎么回事
* * * * *
### 時鐘震蕩
[【10分鐘速成課:計算機科學】第7集-CPU&時鐘頻率_趣味科普人文_科技_嗶哩嗶哩](http://m.bilibili.com/video/av12881976.html#tt_daymode=1)
> CPU以固定的頻率震蕩運行,超頻后功率也會增加,并且會不穩定,低頻功耗降低,但是運算能力降低。可見任何高級的東西,其實本質都很樸素,都是基本顯而易見的原理,背后靠的都是樸素原始的蠢方法。
不過還是不要忘記上面討論的,要注意的問題,時鐘頻率不會受影響嗎。任何時候不要忽視細節,特別是重要的,但不起眼的細節,這種細節往往最關鍵。
[1秒究竟為什么是1秒?](https://mp.weixin.qq.com/s/tZN3eBZUflL9Xn6b1sS0_Q)
> 時間同重量、長度一樣,都需要一個參照物才能表示。
* * * * *
### 問題的本質在哪里
linux計劃任務那種不阻塞定時器,如果間隔很短,任務耗時很長,會出現任務同時在執行,甚至大量任務事件堆積,特別是任務涉及到資源搶奪時,大量任務會堆積阻塞,效率很低,所以你間隔頻率快也是沒用的。阻塞的情況,任務太耗時,你睡眠時間短也是沒用。總之性能出在阻塞上,要找到問題的本質原因,深入研究,才能從根本上優化性能問題,否則抓不住本質,任何方法都是徒勞的。
[硬見創客,三分鐘帶你了解單片機時鐘電路和振蕩源!](http://www.toutiao.com/a6452301460725039629/?tt_from=weixin&utm_campaign=client_share&app=news_article&utm_source=weixin&iid=12619555732&utm_medium=toutiao_android&wxshare_count=1)
[【C++札記】C++11并發編程(一)開啟線程之旅](http://mp.weixin.qq.com/s/DypfPCogpsvcYRodXqjalQ)
> ……那么有沒有方法解決上面的問題了,答案是肯定的,這就是我們下一篇需要講述的內容。在本系列的下一篇文章中,我們將看到如何使用鎖機制控制線程的執行順序。
* * * * *
### 薛定諤的貓
事物真的是按照我們理解的那樣嗎?或者作為觀察者,當我們決定觀察時,結果就不是原本的答案了,我們永遠看不到真相,只要我們去觀察,就不會得到本來的模樣,這就是薛定諤的貓。
* * * * *
### 計劃任務 與 定時程序 的關系
定時任務和計劃任務。linux那是計劃任務,計劃什么時候執行的任務,但是可以每天,重復,比如每個月幾號。其實我們定的鬧鐘就是計劃任務,但是鬧鐘程序本身,檢測我們設置的鬧鐘并執行的程序,它是定時任務,鬧鐘肯定有個常駐進程每隔1秒鐘檢測一次,這個程序就是定時任務,也就是說,鬧鐘是定時任務執行著計劃任務。
**定時程序執行任務時的細節 —— 是否阻塞**
不過我們還是注意不要忽略里面的細節,定時程序執行任務時會不會被任務阻塞,也就是它到底是通過什么方式取得任務并去執行任務的。
js的事件循環,就有點像定時器,調用延時函數后,定時器會在指定的時間把函數加到事件循環里面,形成隊列,但是js是單進程的,所以隊列里面的任務執行會相互阻塞。
進程調度,調用,一個進程是通過什么方式調用另一個進程,調用執行另一個進程時自己是否被阻塞,是否有不同的調用方式,以滿足阻塞和非阻塞的調用,如果使用多進程,那么進程是否越多越好,受機器性能限制,那么這個線程數量,進程數量和機器配置在一個什么比例上才是平衡的。(可能類似于一個寬度已知的馬路上同時行駛多少輛汽車時再能最大發揮運載能力)
* * * * *
### 交互程序 & 程序的生命周期
目前接觸到的程序執行有兩種方式,被訪問,比如php,用戶訪問時執行文件。js有兩種,加載后自上而下的主線程執行,還有事件綁定的觸發。c語言有main函數做主入口。
js事件就是程序的交互(事件機制是利用事件循環實現的),有些程序需要和使用者交互,我們日常使用的大部分軟件、游戲都是這樣的。
再復雜的問題,在高級的方案,最終也會回歸到最樸素的實現上面去,整個計算機都是如此。
> 網頁web訪問式程序,有一個主流程,主流程執行完后程序就結束了,而桌面客戶端軟件,雖然也有一個main主體,但是主流程執行完只是啟動一些進程,這些進程并不會隨著主線程執行完而關閉,而是一直在后臺等待著與用戶交互,比如游戲,以及我們常見的幾乎所有的程序,比如QQ,文件管理器等等都是這種的。
> 一般的程序,代碼從上到下,一溜煙就執行完畢退出了,所以要靠不斷地循環來保持活著。(保持活著,一定要以某種方式不退出,被其他程序喚醒,被其他程序執行調用,嚴格來說不算活著,除非恢復到原有的上下文環境,這就是系統的進程切換了)
**其實這就是程序的生命周期。**
[回歸本質 · 產品設計 · 看云](http://www.hmoore.net/xiak/product/405382)
* * * * *
### 監控/監聽是定時器嗎?
gulp文件監控是什么原理,底層怎么實現的,是定時器嗎,每隔一秒掃描檢測文件是否變化?
監聽怎么做到了文件變化了就能知道了,**這么智能?**
還有進程間通信,信號監聽,這個信號監聽是什么原理,發信號是什么原理,觸發,還是定時掃描監聽?
待研究……
[Everything Search Engine這款軟件如何做到如此快速的搜索的? - 知乎](https://www.zhihu.com/question/22862246/answer/23020795)
> 實現對所有磁盤文件變化的監測. 你看到everything,可以在你復制一個文件之后,又在everything搜索列表內馬上顯示出來. **其實是everything本身會創建好幾個線程,去監視所有磁盤的USN變化**. 變化包括 文件的 增 刪 重命名等.這個時候everything就要實時更新自己的文件索引庫. https://www.zhihu.com/question/22862246/answer/23058016
[swoole+inotify實現異步實時文件監控 - matyhtf的個人空間 - 開源中國](https://my.oschina.net/matyhtf/blog/343508)
[Linux inotify功能及實現原理 - 靜之深 - 博客園](https://www.cnblogs.com/jingzhishen/p/3738637.html)
[真正的inotify+rsync實時同步 徹底告別同步慢 - Jacky's Blog - 博客園](https://www.cnblogs.com/jackyyou/p/5681126.html)
[定時任務常見實現方式](https://mp.weixin.qq.com/s/MbaMgkRfvMUVt1i3a_nFtg)
* * * * *
### 這個世界的運作方式
電子手表是依靠時鐘震蕩電路定時的,機械手表是靠發條定時走動的,發條和齒輪,發條提供動力,齒輪控制定時間隔與指針轉動度數。世界上根本就沒有什么神奇,尤其是技術,再富有技術含量的科技,背后底層往往都是一些最簡單的常識和科學知識組成的。
這個世界上根本就沒有什么**智能**,如果存在,那就存在上帝,但是上帝是不存在的。
如果真的存在智能的話,就監聽就監聽,想什么就是什么,想要什么樣就有什么樣,那還用我們這么辛苦的編程干什么?
只有簡單,憨厚愚蠢的方法,樸素的事實。任何事情都是這樣的。
如果要真說智能的話,生命才是智能的,人才是智能的,大腦才是智能的,計算機只是人造出來的工具,相對于人而言它運算非常快,但是它也優缺點,畢竟它只是個冰冷的機器,人雖然很智能,但是也有缺點,任何事物都是相對的,萬物的規律,本質都是相通的,生命是最美好的,所以無論何時都要敬畏生命。
參考:[javascript - 究竟能不能用死循環?或者其實我們就活在一個死循環的世界中? - SegmentFault](https://segmentfault.com/q/1010000009586182)
> 或者我們人就是個死循環,再不斷的接受信息,然后作出反饋,不然你喊我,我能立即回答,你真以為是你通知我了嗎,是你擁有回調我的能力嗎?搞笑!是我一直在監聽著好嗎?
https://developer.mozilla.org/en-US/docs/Games/Anatomy
> 網頁游戲的 JavaScript 主循環應該怎么寫,這篇文章一步步進行了講解。
* * * * *
### 關于人的大腦
我覺得大腦是個很高級的東西,我們通常說心里想什么,其實心臟并不能想什么,我們人的思維,情緒實際上都是有大腦掌控的。大腦控制神經,人就可以做任何事情,比如吃飯喝水,走路,這些都是大腦控制的。
大腦也很奇怪,人的思維虛無縹緲,天馬行空,根本抓不住,就像我現在大夏這行字的時候,我腦海里面飛快的想著一些事情,可能在想下一個字打什么,怎么組織語句,同時我又在想一些別的事情。
有時候我思緒很快,很亂,有時候突然想到的東西立馬就忘記,完全記不得了,很多人應該有過這樣的體驗,你突然想說個什么事,但是剛要說的時候,腦子好像斷電了,不記得你本來想要說什么了。
我們很多時候都是一心二用,我一邊在打字,一邊想著等會水燒開了我要起來倒水,又或者我的思想跑到明天去了,突然想到明天有個什么重要的事,總是我的思想我自己都抓不住,它太跳躍了,但是我好像發現一個規律,那就是它盡管很活躍,但是它同一時刻只能想一件事情,雖然看起來我在同時想多個事情,但其實同一時刻只是在想一個事情而已,只不過大腦切換很快而已。有的人可能會說,我就是可以同時做幾件事情,并且都能夠做好啊,我并不是說你不能同時做好幾件事情,我是說同一時刻你大腦里面真能同時想幾件事情嗎,你嘗試幾次,你感覺一下這個區別,是不是這樣的。
我們還能通過大腦感覺到疼痛,比如熱水濺到手上會疼。這是神經的作用,皮膚上的神經感受細胞感受到高溫后,向大腦傳遞了信息,大腦發出神經反射,于是我們就甩手了。
于是我們得出結論:
- 大腦是單進程的,只不過切換和運行速度很快。
- 大腦是有記憶里的,但是記憶會隨著時間的推移而逐漸流逝,所以需要不斷加強記憶才能不容易忘記。
- 大腦是個中央處理器,身體的神經細胞相當于傳感器(比如聽覺,嗅覺),傳感器受刺激后,把神經信號發送給大腦,大腦做出反應,比如問到臭味你會捂住口鼻。(當然有一些低級簡單的行為只是簡單的神經反射,不需要經過大腦處理的),所以這個不算是大腦監聽周圍環境,而是環境刺激神經,大腦受到信號了,也就是觸發。
- 大腦也有類似于CPU的三級緩存,用于加快處理速度,比如,對于經常做的事情,人會比較習慣,這類事情,如果遇到突發情況,大腦根本來不及反應,但是人出于本能也會按照正常情況反映一樣。
- 大腦是單進程的,自然會有并發問題,如果很多事情突然在意瞬間來了,大腦一下子收到這么多神經信號,讓你根本來不及反應過來,也就是常說的大腦還沒反應過來,這就是大腦遇到并發問題了。這種情況,如上面所說,有一種本來,那就是長期形成的習慣,這類反應動作,在大腦里面會形成記憶(類似CPU的三級緩存),這類事件處理時就會快很多,不需要太多的思考,我們常說的本能就是這種。比如你很愛你的女朋友,讓用生命去保護她你都不會猶豫一下,每次都是用右手牽著她過馬路,突然有一天,有一輛車要撞向你們,非常突然,人根本來不及反應,此時你本能的反應就是推開女朋友(通常也叫做下意識的動作,就是無意識而自主根據某種習慣而做的動作),用自己的生命去保護她的安全,這種行為就是你的本能,你甚至都沒有經過大腦思考,就做出這樣的反應,這是為什呢,因為你太愛她了,你已經養成習慣保護她了,所以在遇到危險的時候,你本能就是這么做。
- 至于有些節目里面的天才,能左腦右腦同時運用的人,我就不知道了。以上只是我的自我感受。
>[danger] 池老師在《MacTalk·人生元編程》中 \[并發的錯覺\] 一文中也討論了這個問題。
[看這美國少年在做什么,就知馬斯克為啥要做腦機接口的神秘公司了](https://www.ixigua.com/a6493300123173388813/?utm_source=toutiao&utm_medium=feed_stream#mid=6466670596)
[為什么手指泡水一段時間就會發皺?看完長知識了!](https://www.toutiao.com/a6492992224215695886/?tt_from=weixin&utm_campaign=client_share&app=news_article&utm_source=weixin&iid=12619555732&utm_medium=toutiao_android&wxshare_count=1)
> 這說明變皺是一種自主行為而不是被動結果,是由自主神經控制血管收縮造成的無意識反應,就像我們的呼吸和心跳一樣。
> 下意識,又名“潛意識”。心理學上指不知不覺、沒有意識的心理活動,是有機體對外界刺激的本能反應。下意識僅從心理學意義上講,即人的不自覺的行為趨向或受到外界影響不受控制做出的自然反應。
* * * * *
### 一切最終都是為了解決問題
所有東西都是要以解決問題為根本,不要迷失了自己,忘記了自己最初要的是什么,很多時候,秒級的定時器夠了,一秒對我們來說過得很快,我這一句話說出來就過了幾秒鐘了,不要過分追求最小的時間粒度,當然有特殊情況對時間要求的級別特別高,但是我們絕大部分應用是沒有那樣的要求的,能解決問題就可以了,哪怕一開始解決問題的方式不夠優雅,甚至有很多缺陷,那也沒有關系,要知道在這個快速發展的社會中,擁抱變化,快速實現,快速推進,快速迭代,打破常規,迅速占領消費市場,才是最重要的。
* * * * *
### 監聽:詢問/觸發(主動/被動)
要監聽一個事件,知道一個事物的狀態,有兩種方式,第一定時不斷地詢問,這個缺點就是效率低,時效性不好,當然時效性取決于循環頻率,而頻率過快又會影響效率。第二種就是事物發生狀態改變時自己通知你,這種是最理想的方式,效率高,沒有不必要的輪詢,也沒有什么時效性的問題,幾乎可以認為是實時的,但是這種方式需要監測著提前與被監測者建立關系,建立訂閱的關系,當事物的狀態改變時,就能發信號通知到監測者。隊列主要使用第一種定時輪詢的方式,只不過是優化了的,而互聯網接口的webhook是第二種方式,比如你要監測淘寶的某個接口,或者是監測微信支付接口的支付結果,你應該是等它狀態發生改變時自己通知你,而不是你不斷地去輪詢它,當然有些時候,你甚至可以兩種方式一起使用,不過要注意解決你業務中可能出現的并發問題。開發任何程序,在設計之初,在每一個環節,并發情況都是時刻要考慮的。
不知道sook通信的底層是怎么做的,進程間的通信,端口的監聽,信號,是怎么做的。
猜想一:應該是第二種通知方式和第一種輪詢結合,不過通知占大部分比例,關鍵的設計理論應該通知,輪詢為輔。應該是計算機總線控制所有信號的分發,信號由總線傳遞給其它進程的—通知。而總線是通過晶體時鐘震蕩電路感知收到進程發來的信號的—輪詢。
猜想二:所有的東西都可以看成文件,信號也可以當成文件,比如nginx搭配php的工作方式就是就是監聽127.0.0.1:9000.sook文件,所以每個信號在系統里面都對應一個文件,要監聽信號直接監聽對應的文件就可以了,sook通信可能就是這樣的。當然怎么做到監聽文件的具體細節又不得而知,可能就是第一種輪詢的方式。
思考,如果是輪詢,如果循環不等待,直接寫無限循環的代碼,那一秒鐘能執行多少次呢,這個不同的編程語言應該不同吧,并且cpu是時間分片執行,在多個進程中快速切換的,所以不可能等同cpu的時鐘吧,除非cpu只有這一個任務,但顯然不可能cpu肯定還會被系統的其它進程所占用,所以這還取決于當前cpu的負載,有多少任務再執行。不過cpu真累啊,能者多勞嘛,誰叫它運行那么快呢。
> 對于萬物論來說,每時每刻都有事件發生,你覺得什么時候發生,那是相對觀察著的,即使沒有觀察者,事件也在發生,但是這樣我們就不知道了,所以通常我們所說的發生,其實都是站在觀察者的角度的。
>[danger] 而無論是主動還是被動,首先活著才是最重要的,活著是一切的可能,是一切的基礎,而活著是要主動的,計算機天然的能主動的活著,那就是時鐘震蕩電路,CPU的震蕩頻率,CPU的心跳,已經這么快了,這足夠成為一切的基礎。
[Intel 酷睿i7 7700K](http://detail.zol.com.cn/1158/1157756/param.shtml) CPU主頻:4.2GHz
4.2 \* 10^9 HZ,即1秒鐘有4.2 \* 10^9個周期。
(赫茲是電,磁,聲波和機械振動周期循環時頻率的單位。即每秒的周期次數(周期/秒)。)
* * * * *
[【底層原理】用戶進程緩沖區和內核緩沖區](https://mp.weixin.qq.com/s/W8GGupa6FuizbWU9CJ5B_Q)
> 計時器:計算機能計時是因為晶體振蕩器產生的電磁脈沖。那么所有的定時任務都是以它為基礎的。
>
> (電扇里面的定時器是個扭力發條,這樣記時并不精確,使用年限越長越不準了)
> 當然,write并不一定導致內核的寫動作,比如os可能會把內核緩沖區的數據積累到一定量后,再一次寫入。**這也就是為什么斷電有時會導致數據丟失。**
我將繼續探尋計算機工作的一些核心,找尋本質。(堆棧,內存管理,中斷,晶體振蕩器,三極管,總線,進程,線程,協程,CPU調度,IO,TCP/IP)
* * * * *
### 操作系統之上 — 抽象
編程界的鎖是系統實現的,計算機本沒有鎖的概念,也就是說鎖是人們設計系統時抽象出來的,計算機本身并不具備這個概念,也無法規避并發問題,如果系統不實現鎖就會有很多麻煩的事不好處理,比如并發的問題,計算機底層一會傻傻的做事,cpu甚至只知道一條一條的處理指令,這些指令并不是來自同一個進程的連續指令,因為cpu的時間被分片了,所以它壓根就不在乎它在做什么,當然也就沒有程序概念了,它不知道并發寫文件會出現什么,這不是它要考慮的問題,因為它根本就不在乎,這是你程序的邏輯的問題,只有你在乎,所以,你不考慮并發,不加鎖,讀寫文件,內存就會出現和你預期不一樣的結果,也就是你寫的程序有問題。比如文件亂碼,運行結果不符合預期,這就是你的問題了,你寫的BUG,這么來看,對于cpu來說,并沒有什么bug,你認為的bug對它而言就是簡單的指令而已。其它的它不在乎,它只單純的活在自己的世界里。僅此而已。
并發卻是現實世界中真真切切存在的問題,比如排隊買票,幾乎我們每天的生活都與并發有關,因為在我們的生活中,我們不僅僅是一個單獨的個體,我們要融入這個社會,是要和他人打交道的。把個體的人看作進程的話,社會看作運行的計算機的話,就會清晰很多,這個環境中無時無刻不在進行著并發。
它不知道什么是對和錯,對它而言,或者說在它的世界里,本就沒有對和錯的概念。
* * * * *
### 并發
做并發編程之前,必須首先理解什么是并發,什么是并行,什么是并發編程,什么是并行編程。
并發(concurrency)和并行(parallellism)是:
解釋一:并行是指兩個或者多個事件在同一時刻發生;而并發是指兩個或多個事件在同一時間間隔發生。
解釋二:并行是在不同實體上的多個事件,并發是在同一實體上的多個事件。
解釋三:在一臺處理器上“同時”處理多個任務,在多臺處理器上同時處理多個任務。如hadoop分布式集群
所以并發編程的目標是充分的利用處理器的每一個核,以達到最高的處理性能。
[并發和并行有什么區別? | 并發編程網 – ifeve.com](http://ifeve.com/parallel_and_con/)
> 任何事情是相對的,理論上存在同一時刻,但是卻無法實際證明,因為時間可以無限細分,所以即使我們說的是某一時刻,其實也是某一時間段。
[php非阻塞訪問url 解析socket阻塞與非阻塞,同步與異步 - 橙虛緣空間 - CSDN博客](http://blog.csdn.net/qq43599939/article/details/50570098)
* * * * *
### 程序:單進程/多進程(單線程/多線程)
程序分為兩種,單進程和多進程程序,程序的執行引起資源的爭奪,就出現了并發,由這引發出串行,并行,異步,同步,阻塞,非阻塞等概念和問題。不過現在的程序,基本都不是單進程程序了,特別是網絡程序,誕生之初就是為了服務大量用戶的,并且多進程程序能充分利用cpu,提高軟件的效率。當然特殊情況也有單進程的程序,比如瀏覽器中的js就是單進程的,這是為了降低復雜度,和提高dom的操作效率。
* * * * *
### 來源于生活
生活中的事件監聽,比如光控開關,聲控開關,就是觸發通知式的,比如光照不同引起光敏電阻的反應,聲波震動觸動了聲控薄膜,這就是傳感器監聽外界信號的物理案例。任何東西都能在自然界,生活中找到相似之處,找到靈感,和影子。
* * * * *
### 關于循環
循環分為 有限循環 和 無限循環 ,無限循環又有 可控 和 不可控 兩種。死循環 即 不可控的無限循環(老師常說的不要寫出死循環BUG就是指不可控的無限循環了),可以理解成系統中有一個失控的進程了,此時只能使用kill來終止殺死這個進程了。
BUG = 死循環 = 無限循環 + 不可控
我們平常為了簡單,表達上有一些歧義,容易把 死循環 理解成了 無限循環 了,其實這個說法有很大問題,以后還是要避免這樣的問題,任何時候必須用準確的詞語來表達意思。
當我們說 無限循環 的時候一般默指為 可控的無限循環,但這種習慣真的很不好,一定要表達清楚。
[javascript - 究竟能不能用死循環?或者其實我們就活在一個死循環的世界中? - SegmentFault](https://segmentfault.com/q/1010000009586182)
《Ruby元編程》里的一句話說的很好,我感覺放到這里很合適
> 根本沒有什么元編程,從來只有編程而已。
我認為死循環也是一樣,存在即為合理,只是看你如何去用而已,在沒有更好的解決方案的時候,解決問題很重要,在有更好的解決方案的時候,代碼優雅同樣重要,根本就沒有什么死循環,從來只有循環而已。
* * * * *
[Html5+Lufylegend.js游戲開發(一)引擎介紹及原理 - 奔跑的QQEE - 博客園](https://www.cnblogs.com/wuyiblogs/p/5878308.html)
> 在游戲中,有一個比較重要的元素就是ENTER_FRAME時間軸事件,時間軸事件說白了就是死循環
受學習php影響,腳本執行有超時和內存限制(命令行模式沒有這個限制),這就意味著腳本不能夠長時間執行。所以潛意識中所有程序都是這樣的,不能接受無限循環的代碼,**覺得程序應該盡早執行完并退出,甚至受web訪問式影響,只能寫出被動運行的代碼,不了解常駐服務程序的結構。** 但其實并不是這樣的,這是思維受禁錮了。

游戲就是一種無限循環,畫面就是一幀一幀不斷循環而顯示出來的。[【游戲開發】Unity游戲開發零基礎入門教程_嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili](https://www.bilibili.com/video/av13288553?from=search&seid=12795476358543930858)

要加死循環,不加的話exe運行一次就會退出
[手把手教你如何將翻譯程序打包成exe文件](https://mp.weixin.qq.com/s/ux9XuqDKgPC6uKzV-olOFQ)
[wxPython:一套Python語言的GUI工具箱](https://mp.weixin.qq.com/s/Jj-a14jf_PZpLRnglsmp3A)
> app.MainLoop() # Then start the event loop.
>
> **事件監聽,窗體運行,就是一個無限可控的循環。** 沒有循環,程序也就執行完畢關閉了,這種編程方式和傳統的web模式有很大的區別,web模式,一個請求的腳本要很快執行完畢并結束。
* * * * *
[一個自動加濕器的制作過程,程序的作用有多大,看了便知!](https://www.365yg.com/a6545636034074378766)
> 主循環是死循環嗎?
> 是的 重復執行程序任務。
* * * * *
[處理億級數據的“定時任務”,如何縮短執行時間?](https://mp.weixin.qq.com/s/aN-M8YcwXNE462HaVrQ6ig)
[從Timer類源碼分析,猜想今日頭條的取消推薦文章的技術實現](https://www.toutiao.com/i6488636316970910222/?tt_from=weixin&utm_campaign=client_share&app=news_article&utm_source=weixin&iid=12619555732&utm_medium=toutiao_android&wxshare_count=1)
> 你那個死循環合不合適啊
關鍵字:BUG,死循環,無限循環,不可控循環,可控循環
[在WordPress中使用wp-cron插件來設置定時任務](http://www.jb51.net/article/76183.htm)
[PHP實現執行定時任務的幾種思路詳解 - Web烤貓 - SegmentFault](https://segmentfault.com/a/1190000002955509)
[基于Laravel Task-Scheduler定時發送郵件小程序 - 來生做個漫畫家 - SegmentFault](https://segmentfault.com/a/1190000005057786)
[Laravel 5.2 文檔 服務 —— 任務調度 – Laravel學院](http://laravelacademy.org/post/3267.html)
[詳解PHP實現定時任務的五種方法_php技巧_腳本之家](http://www.thinkphp.cn/topic/42571.html)
> 定時運行任務對于一個網站來說,是一個比較重要的任務,比如定時發布文檔,定時清理垃圾信息等,現在的網站大多數都是采用PHP動態語言開發的,而對于PHP的實現決定了它沒有Java和.Net這種AppServer的概念,而http協議是一個無狀態的協議,PHP只能被用戶觸發,被調用,調用后會自動退出內存,沒有常駐內存。
[PHP 實現定時任務的幾種方法 - ThinkPHP框架](http://www.thinkphp.cn/topic/42571.html)
[PHP實現定時任務的幾種方式-PHPChina開發者社區-權威的PHP中文社區](http://www.phpchina.com/portal.php?mod=view&aid=41051)
[php 定時任務_百度搜索](https://www.baidu.com/s?wd=php+%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1&ie=utf-8&rsv_cq=php+%E5%8D%95%E4%BE%8B&rsv_dl=0_right_recommends_20807&euri=5c209d60170a7167991896a99f87be1f)
**思考:**
代碼中的無限循環,CPU是怎么對待的呢,永久占用CPU的時間片段嗎,那其他程序不是都沒執行機會了?還是優先級高一些而已?
有答案了,系統會強制讓進程讓出CPU時間片的。
[小白科普:線程和線程池](https://mp.weixin.qq.com/s/qzoLgNNSZD2NrzBEINVuUg)
~~~
問:一個web端過來的請求是不是就意味著占用著一個進程 如果是cpu密集型操作就會一直占用該進程直至請求結束 并發情況下其它請求需要等待空閑進程?
回復:即使是CPU密集型, 也會在時間片到期的時候,讓出CPU的。然后OS再調度,看看誰來執行。
~~~
[一分鐘了解nohup和&的功效](https://mp.weixin.qq.com/s/nyT-FPdIUdJUiUCYVGEnTg)
~~~
問:環程序,在實際軟件中,有沒有應用呢?以前學校老師c語言的課上總說,千萬不要寫出死循環的代碼,死循環就是最嚴重的BUG。不知道是不是這樣的,但是感覺現在很多軟件,比如隊列,監聽接口等,底層實現好像都是死循環,別人說這叫,空循環,無限循環之類的,并不認為死循環是BUG。同時我還想知道,這樣死循環的代碼,CPU是怎么對待的,會持續搶占cpu時間片嗎,如果這樣,那別的進程怎么辦?希望大神解答一下,或者給個提示讓我去找找資料。謝謝了!
回復:服務(service)的本質就是死循環程序,監聽端口,接收并響應請求
服務的本質就是死循環,哈哈,那么就剩第二個問題了,cpu如何對待死循環的程序?
~~~
* * * * *
### 單例定時程序
定時程序,常駐程序要注意以單實例模式啟動,不能同時啟動多個,否則會出現重復執行并發等問題,這就違背了設計的意圖了。
> ### 13.5 單實例守護進程
> 為了正常運作,某些守護進程實現為,在任意時刻只運行該守護進程的一個副本,例如,這種守護進程可能需要排它地訪問一個設備。對cron守護進程而言,如果同時有多個實例實例運行,那么每個副本都可能試圖開始某個預定的操作,于是造成該操作的重復執行,這很可能導致出錯。
……
如果每個守護進程創建一個固有名字的文件,并在該文件的整體上加一把寫鎖,那么只允許創建一把這樣的寫鎖。在此之后創建寫鎖的嘗試都會失敗,這向后續守護進程副本指明已有一個副本正在運行。
(UNIX環境高級編程第三版 P-380)
[自動化 - 關于php 自動/定時 執行函數 (將api中的數據每十分鐘錄入數據庫) - SegmentFault](https://segmentfault.com/q/1010000011365312)
> 記得每次訪問加個鎖,比如文件鎖.避免重復執行的問題
[redis - PHP用什么來快速消費隊列 - SegmentFault](https://segmentfault.com/q/1010000004326627)
> 此shell要判斷當前有沒有消費進程在
* * * * *
last update:2018-1-5 15:00:44
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 科目一
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南