同步代碼主要是指調用某個邏輯時,會等待到該邏輯返回調用結果.
例如:php
<?php $num = 30; $result = M('test')->select();//僞代碼,查詢數據庫 sleep(3);//僞代碼,當成執行了3秒才返回 echo json_encode($result);//返回數據
只有當select查詢到數據時,纔會返回數據給$result,這個值必定是數據庫操做完畢返回的值ajax
例如:sql
<?php $num = -30; $result = abs($num); echo json_encode($result);//返回數據
abs會返回數據給$result,這個值必定是abs正確操做的值數據庫
例如:
用戶請求www.easyswoole.com,頁面會一直等待easyswoole響應數據.json
例如:swoole
<?php //模擬發送郵件中 $status = send(); sleep(30);//發送郵件花費30秒 echo "發送郵件".$status?'完成':'失敗';
等待發送郵件的成功/失敗,就是同步異步
異步代碼主要是指調用某個邏輯時,不會等待該邏輯返回的結果,只會返回是否已經調用的最初結果(或不返回)
例如:socket
調用$.ajax(),默認狀況下是異步ajax,它會繼續往下執行代碼,當有結果返回時經過回調事件進行處理.函數
例如:網站
<?php $pid = pcntl_fork(); if ($pid == 0) { //子進程 //模擬發送郵件 sleep(30);//發送郵件花費30秒 exit(0); } pcntl_waitpid($pid, $status, WNOHANG); echo "發送郵件中";
經過新開一個進程去處理髮送郵件的任務,在當前進程中不關心發送郵件的結果,直接往下執行
正在運行的進程因爲提出系統服務請求(如I/O操做),但由於某種緣由未獲得操做系統的當即響應,或者須要從其餘合做進程得到的數據還沒有到達等緣由,該進程只能調用阻塞原語把本身阻塞,等待相應的事件出現後才被喚醒。
正在進行的進程因爲發生某事件而暫時沒法繼續執行時,便放棄處理機而處於暫停狀態,亦即進程的執行受到阻塞,咱們把這種暫停狀態叫阻塞進程阻塞,有時也成爲等待狀態或封鎖狀態。一般這種處於阻塞狀態的進程也排成一個隊列。有的系統則根據阻塞緣由的不一樣而處於阻塞狀態進程排成多個隊列。
例如:
用戶訪問服務端,請求用戶的我的的訂單信息,因爲數據庫數據量大,數據庫繁忙,sql語句查詢了3秒才返回,這個查詢數據庫的過程,就是可稱爲是"阻塞的".(進程調用外部邏輯)
阻塞這個概念和時間關係不大,就算查了0.1秒,也能夠說是阻塞了0.1秒,由於這個並非進程自己執行所消耗的時間,而是由於查詢數據庫,等待數據庫響應消耗的時間. 但阻塞的危害性和時間有關,阻塞0.1秒對於用戶是沒有任何問題的,可是阻塞10秒將會使用戶體驗降低不少,因此咱們須要重視阻塞
用戶訪問服務端,因爲某個地方調用了死循環或多重循環浪費了許多時間,沒法繼續往下執行,這個狀態也可稱爲阻塞.(非進程阻塞,可自行避免)
非進程阻塞 在進程阻塞層面中,並不算是被阻塞了,由於它依舊在執行進程中的代碼,沒有等待清空
如上所說,調用數據庫等外部邏輯,形成阻塞的函數,就叫作阻塞函數
在php初級開發者中,或許沒有聽過這個概念,阻塞每每是和"同步"概念一塊兒存在的,例如查詢數據庫,獲取文件數據,請求其餘網站,等等,只要須要消耗非進程自己執行時間並須要進程等待(同步)的,均可以說是阻塞.
幾乎全部的阻塞,都是與I/O有關.
阻塞必定是同步代碼調用阻塞函數纔會阻塞,但同步代碼不必定會阻塞(不調用阻塞函數的同步代碼)<?php $num = 30; $result = M('test')->select();//僞代碼,sql阻塞 sleep(3);//僞代碼,當成執行了3秒才返回 echo json_encode($result);//返回數據
可自行搜索瞭解更多
非阻塞,顧名思義,就是在進程在運行中,不存在阻塞狀況,一直能往下執行.
非阻塞通常是指調用I/O操做時,進程無需等待I/O操做,直接往下執行的狀況 非阻塞一般是和"異步"概念一塊兒存在,只要是異步獲取I/O,就必定是非阻塞
異步調用I/O必定是非阻塞的,但非阻塞不必定須要異步調用纔可實現(非阻塞模型)
例如:
當查詢數據庫時,立刻返回狀態(查詢到了就返回數據,數據還沒到就返回-1),程序能夠當即往下執行邏輯.
這種立刻返回結果,無需等待(並不必定有數據)的函數,就叫作非阻塞函數,也可稱爲是"異步調用"
能夠經過非阻塞模型去實現非阻塞(主要針對於server服務端實現). 詳細瞭解可查看:http://www.php20.cn/article/157
php初級開發者中,不多有非阻塞這個概念存在,但php是有非阻塞的,例如socket_set_nonblock()函數,將socket改成非阻塞狀態
經過flock($file,LOCK_EX|LOCK_NB),可將文件操做設置爲非阻塞狀態
可自行搜索瞭解詳細
因爲非阻塞的返回結果是不肯定的,當咱們須要關心返回結果的狀況時,須要確保返回結果是正確的(例如while(1){}定時查詢,當數據正確返回退出循環),或者直接使用阻塞函數
阻塞:
小明去電腦店買Mac,問店員如今有沒有MacBook Pro版本,有多少臺,店員告訴小明,"我得去查一查,你得等等",小明站在店門口等了2天,店員回來了,告訴小明,如今有10臺,而後小明買了一臺.
在這個過程當中,店員查詢是否有mbp的動做,就屬於I/O操做,叫小明等等這個操做,就是阻塞狀況,小明等了2天,就說明查詢mbp時間爲2天,阻塞了2天,店員回來告訴小明有10臺,就是阻塞函數出現告終果,並返回了數據,小明買了一臺,就是繼續往下執行了代碼
非阻塞: 小明去電腦店買Mac,問店員如今有沒有MacBook Pro版本,有多少臺,店員告訴小明,"我得去查一查,你先回去唄",小明回家,每隔10分鐘打電話給店員,可是店員每次都告訴他還沒查到,小明每次打完電話就去敲PHP代碼,2天后,小明打完一把LOL,又打電話給店員問,店員告訴小明,如今有10臺了,而後小明買了一臺.
在這個過程當中,店員查詢是否有mbp的動做,就屬於I/O操做,叫小明回家這個操做,就是非阻塞狀況,小明不斷打電話,這個就是定時輪詢查詢,店員不斷的回覆,這個狀況就是非阻塞函數沒有返回數據,小明去敲PHP,說明非阻塞狀況還能執行其餘代碼,2天后,店員回來告訴小明有10臺,就是非阻塞函數經過輪詢出現告終果,並返回了數據,小明買了一臺,就是退出了循環繼續往下執行了代碼