[TOC]
# 特點
協程有以下特點:
(1)協程的調度由應用程序調度器控制,調度器由開發應用程序者編寫。協程在應用層面,進程和線程在操作系統層面。
(2)協作式的調度方式。由自己交出cpu執行權。
(3)減輕了OS處理零散任務和輕量級任務的負擔。
(4)消耗更少的資源
Php支持協程的版本(PHP 5 >= 5.5.0, PHP 7)
第一點,yield表達式兩邊的括號在PHP7以前不是可選的, 也就是說在PHP5.5和PHP5.6中圓括號是必須的.
第二點,你可能已經注意到調用current()之前沒有調用rewind().這是因為生成迭代對象的時候已經隱含地執行了rewind操作.
~~~
function gen() {
yield 'foo';
yield 'bar';
}
$gen = gen();
var_dump($gen->send('something'));
// 如之前提到的在send之前, 當$gen迭代器被創建的時候一個renwind()方法已經被隱式調用
// 所以實際上發生的應該類似:
//$gen->rewind();
//var_dump($gen->send('something'));
//這樣renwind的執行將會導致第一個yield被執行, 并且忽略了他的返回值.
//真正當我們調用yield的時候, 我們得到的是第二個yield的值! 導致第一個yield的值被忽略.
//string(3) "bar"
~~~
# 生成器
1. 迭代器iterator
將數據集合用對象的方式存儲起來,使用foreach遍歷迭代器實現數據集合的遍歷。
2. 生成器與迭代器
生成器generator實現了迭代器,含有迭代器的方法。generator 是 forward-only 的迭代,在迭代開始后不能 rewind。生成器不能被實例化,也就是直接new。通過含有yield關鍵字函數返回。在函數里面的yield構成了中斷點。
3. yield關鍵字
可以理解為返回生成器函數的中斷點,可以返回數據和向其發送數據。是生成器的關鍵所在。
4. 生成器與協程
協程的支持是在迭代生成器的基礎上, 增加了可以回送數據給生成器的功能(調用者發送數據給被調用的生成器函數). 這就把生成器到調用者的單向通信轉變為兩者之間的雙向通信.
返回生成器的函數中函數體可以理解為一個協程。生成器調用成員函數控制協程的上下文執行
# 代碼
yield的根本實現是生成器類,而迭代器類是迭代器接口的實現
~~~
Generator implements Iterator {
public mixed current ( void ) // 返回當前產生的值
public mixed key ( void ) // 返回當前產生的鍵
public void next ( void ) // 生成器繼續執行
public void rewind ( void ) // 重置迭代器,如果迭代已經開始了,這里會拋出一個異常。
// renwind的執行將會導致第一個yield被執行, 并且忽略了他的返回值.
public mixed send ( mixed $value ) // 向生成器中傳入一個值,并且當做 yield 表達式的結果,然后繼續執行生成器。如果當這個方法被調用時,生成器
// 不在 yield 表達式,那么在傳入值之前,它會先運行到第一個 yield 表達式。
public void throw ( Exception $exception ) // 向生成器中拋入一個異常
public bool valid ( void ) // 檢查迭代器是否被關閉
public void __wakeup ( void ) // 序列化回調,拋出一個異常以表示生成器不能被序列化。
}
~~~
# go的協程
Go調度模型是G(協程)、P(調度器)、M(OS線程)三層構成的。Go系統調用就是同步調用,當前的協程(G)所在的OS線程(M)會被阻塞,但是Go調度器(P)會被剝離出來,尋找空閑或者創建新的OS線程(M)來綁定P,去執行其它等待運行的協程(G)。在Go里面進行大量文件IO操作,會產生大量OS線程(M)
# 參考文章
http://www.laruence.com/2015/05/28/3038.html
http://www.powerxing.com/php-review-generator/
https://yq.aliyun.com/articles/53673
http://www.php230.com/weixin1409789107.html
https://segmentfault.com/a/1190000010576658
- OAuth
- 簡介
- 步驟
- 單點登錄
- .user.ini
- 時間轉換為今天昨天前天幾天前
- 獲取ip接口
- 協程
- 概念
- yield-from && return-values
- 協程與阻塞的思考
- 中間件
- mysqli異步與php的協程
- 代碼片段
- pdo 執行的sql語句
- 二進制安全
- 捕捉異常中斷
- global
- 利用cookie模擬登陸
- 解析非正常json
- 簡單的對稱加密算法
- RSA 加密
- 過濾掉emoji表情
- 判斷遠程圖片是否存在
- 一分鐘限制請求100次
- 文件處理
- 多文件上傳
- 顯示所有文件
- 文件下載和上面顯示所有文件配合
- 文件的刪除,統計,存數組等
- 圖片處理
- 簡介
- 驗證碼
- 圖片等比縮放
- 批量添加水印
- beanstalkd
- 安裝
- 使用
- RabbitMQ
- 簡介
- debain安裝
- centos安裝
- 常用方法
- 入門
- 工作隊列
- 訂閱,發布
- 路由
- 主題
- 遠程調用RPC
- 消息中間件的選型
- .htaccess
- isset、empty、if區別以及0、‘’、null
- php各版本
- php7.2 不向后兼容的改動
- php中的各種坑
- php7改變
- php慢日志
- 郵件
- PHPMailer實現發郵件
- 驗證郵件地址真實性
- 文件下載
- FastCgi 與 PHP-fpm 之間的關系
- openssl 加解密
- 反射
- 鉤子方法
- 查找插件
- opcode
- opcache使用
- opcache優化
- 分布式一致性hash算法
- 概念
- 哈希算法好壞的四個定義
- php實現
- java實現
- 數組
- jwt
- jwt簡介
- 單點登錄
- phpize
- GeoIP擴展
- php無法獲得https網頁內容的解決方案
- homestead運行的腳本
- Unicode和Utf-8轉換
- php優化
- kafka
- fpm配置
- configure配置詳解