日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php7协程通信使用,PHP7下的协程实现

發布時間:2024/10/14 php 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php7协程通信使用,PHP7下的协程实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原標題:PHP7下的協程實現

什么是協程

先搞清楚,什么是協程。

你可能已經聽過『進程』和『線程』這兩個概念。

進程就是二進制可執行文件在計算機內存里的一個運行實例,就好比你的.exe文件是個類,進程就是new出來的那個實例。

進程是計算機系統進行資源分配和調度的基本單位(調度單位這里別糾結線程進程的),每個CPU下同一時刻只能處理一個進程。

所謂的并行,只不過是看起來并行,CPU事實上在用很快的速度切換不同的進程。

進程的切換需要進行系統調用,CPU要保存當前進程的各個信息,同時還會使CPUCache被廢掉。

所以進程切換不到非不得已就不做。

那么怎么實現『進程切換不到非不得已就不做』呢?

首先進程被切換的條件是:進程執行完畢、分配給進程的CPU時間片結束,系統發生中斷需要處理,或者進程等待必要的資源(進程阻塞)等。你想下,前面幾種情況自然沒有什么話可說,但是如果是在阻塞等待,是不是就浪費了。

其實阻塞的話我們的程序還有其他可執行的地方可以執行,不一定要傻傻的等!

所以就有了線程。

線程簡單理解就是一個『微進程』,專門跑一個函數(邏輯流)。

所以我們就可以在編寫程序的過程中將可以同時運行的函數用線程來體現了。

線程有兩種類型,一種是由內核來管理和調度。

我們說,只要涉及需要內核參與管理調度的,代價都是很大的。這種線程其實也就解決了當一個進程中,某個正在執行的線程遇到阻塞,我們可以調度另外一個可運行的線程來跑,但是還是在同一個進程里,所以沒有了進程切換。

還有另外一種線程,他的調度是由程序員自己寫程序來管理的,對內核來說不可見。這種線程叫做『用戶空間線程』。

協程可以理解就是一種用戶空間線程。

協程,有幾個特點:

協同,因為是由程序員自己寫的調度策略,其通過協作而不是搶占來進行切換

在用戶態完成創建,切換和銷毀

?? 從編程角度上看,協程的思想本質上就是控制流的主動讓出(yield)和恢復(resume)機制

generator經常用來實現協程

說到這里,你應該明白協程的基本概念了吧?

PHP實現協程

一步一步來,從解釋概念說起!

可迭代對象

PHP5提供了一種定義對象的方法使其可以通過單元列表來遍歷,例如用foreach語句。

你如果要實現一個可迭代對象,你就要實現Iterator接口:

生成器

可以說之前為了擁有一個能夠被foreach遍歷的對象,你不得不去實現一堆的方法,yield關鍵字就是為了簡化這個過程。

生成器提供了一種更容易的方法來實現簡單的對象迭代,相比較定義類實現Iterator接口的方式,性能開銷和復雜性大大降低。

記住,一個函數中如果用了yield,他就是一個生成器,直接調用他是沒有用的,不能等同于一個函數那樣去執行!

所以,yield就是yield,下次誰再說yield是協程,我肯定把你xxxx。

PHP協程

前面介紹協程的時候說了,協程需要程序員自己去編寫調度機制,下面我們來看這個機制怎么寫。

0)生成器正確使用

既然生成器不能像函數一樣直接調用,那么怎么才能調用呢?

方法如下:

foreach他

send($value)

current / next...1)Task實現

Task就是一個任務的抽象,剛剛我們說了協程就是用戶空間協程,線程可以理解就是跑一個函數。

所以Task的構造函數中就是接收一個閉包函數,我們命名為coroutine。

2)Scheduler實現

接下來就是Scheduler這個重點核心部分,他扮演著調度員的角色。

這樣我們基本就實現了一個協程調度器。

你可以使用下面的代碼來測試:

關鍵說下在哪里能用得到PHP協程。

這樣就提高了程序的執行效率。

關于『系統調用』的實現,鳥哥已經講得很明白,我這里不再說明。

3)協程堆棧

鳥哥文中還有一個協程堆棧的例子。

我們上面說過了,如果在函數中使用了yield,就不能當做函數使用。

所以你在一個協程函數中嵌套另外一個協程函數:

這里的echoTimes是執行不了的!所以就需要協程堆棧。

不過沒關系,我們改一改我們剛剛的代碼。

把Task中的初始化方法改下,因為我們在運行一個Task的時候,我們要分析出他包含了哪些子協程,然后將子協程用一個堆棧保存。(C語言學的好的同學自然能理解這里,不理解的同學我建議去了解下進程的內存模型是怎么處理函數調用)

當Task->run()的時候,一個循環來分析:

然后我們增加echoTime的結束標示:

然后修改echoTimes:

Task變為:

這樣就實現了一個協程堆棧,現在你可以舉一反三了。

4)PHP7中yield from關鍵字

PHP7中增加了yield from,所以我們不需要自己實現攜程堆棧,真是太好了。

把Task的構造函數改回去:

echoTimes函數:

task1生成器:

這樣,輕松調用子協程。返回搜狐,查看更多

責任編輯:

總結

以上是生活随笔為你收集整理的php7协程通信使用,PHP7下的协程实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。