❶ 什麼是同步編程、非同步編程
同步編程:傳統的同步編程是一種請求響應模型,調用一個方法,等待其響應返回。就是一個線程獲得了一個任務,然後去執行這個任務, 當這個任務執行完畢後,才能執行接下來的另外一個任務。
非同步編程:非同步編程就是要重新考慮是否需要響應的問題,也就是縮小需要響應的地方。因為越快獲得響應,就是越同步化,順序化,事務化,性能差化,非同步編程通常是通過fire and forget方式實現。
(1)非同步函數式編程擴展閱讀:
在同步編程中,所有的操作都是順序執行的,比如從socket中讀取(請求),然後寫入(回應)到socket中,每一個操作都是阻塞的。
非同步編程的原則是,讓進程處理多個並發執行的上下文來模擬並行處理方式 ,非同步應用使用一個事件循環,當一個事件觸發暫停或恢復執行上下文:
只有一個上下文處於活動狀態,上下文之間進行輪替,代碼中的顯示指令告訴事件循環,哪裡可以暫停執行,這時,進程將查找其他待處理的線程進行恢復,最終,進程將回到函數暫停的地方繼續運行,從一個執行上下文移到另一個上下文稱為切換。
❷ 函數式編程和響應式編程有什麼區別
1. 我暫且認為你說的RP是指Rx*框架的Reactive programming,(如果不是,就先認為是一下吧)
Rx*框架的RP,其實應該叫FRP(Functional Reactive Programming)(誤,感謝 邵成的指正,具體見補充部分),那和FP基本上就是一種派生(derive)關系了
FRP基本上就是面向非同步事件流的編程了,這個非同步事件流叫:Observable,一般叫:Stream
Stream就是一個 按時間排序的Events(Ongoing events ordered in time)序列
Stream是不可變(Immutability)的,任何操作都返回新的Stream, 且它是一個Monad(它有map和flatMap方法)。
FRP的關注點在Stream,而FP的關注點在(Type, Operate),Stream -> (Type, Operate)是一種泛化(generic),(Type, Operate) -> Stream 是一種派生。
RP本身是建立於觀察者模式之上的一種編程範式(級別同MV*),FP則更偏向底層解決一般化問題。
❸ 編程語言scala有哪些特點
Scala有互動式命令行(REPL), 可以在上面快速的試各種語法和代碼。這對學習新特性,或者實驗新想法非常有用。(第1章)
一致性: 盡管Scala融合了靜態類型系統、面向對象、函數式編程等語言特性,但卻很少能看出融合的痕跡。Scala是我見到融合最多語言特性而又不顯得雜亂的編程語言之一。
類型安全:Scala創始人是教授,他先帶領創建了java 5編譯器,而後覺得Java有太多羈絆而發明了Scala。 Scala編譯器和類型系統非常強大,它的目標是盡量把軟體錯誤消滅在編寫過程中。 Scala類型系統是圖靈完備的,甚至可以在編譯期間解決問題。
面向對象: Scala是面向對象的編程語言,所有的變數和方法都封裝在對象中,可以把信息封裝起來供外部使用。(第2章)
函數式編程:Scala同時又是函數式編程語言,函數可以獨立存在,可以定義一個函數作為另一個函數的返回值,也可以接受函數作為函數的參數。這給組合函數帶來了很大的便利。如何把面向對象編程形容成搭積木的話,函數式編程就像拼線條,更靈活和更有創意。(第3章)
非同步編程: 由於函數式編程提倡變數不可變,使非同步編程變得非常容易。同時Scala提供的Future(第5章), 和akka類庫(第9-11章),使得非同步編程變得非常容易。
基於JVM: Scala會被編譯成為jvm bytecode,所以Scala能無縫集成已有的Java類庫。你可以非常自然的使用已經存在的非常龐大且穩定的Java類庫,比如小巧好用的apache.common.*, 或者Java上的各種工具類庫。
因為如此眾多特性,用Scala可以優雅地編寫簡潔的代碼,同時又能減少很多低級錯誤;能快速進行開發,又能保證系統性能、團隊協作和長期維護。
❹ C#非同步編程模式IAsyncResult概述
IAsyncResult 非同步設計模式通過名為 BeginOperationName 和 EndOperationName 的兩個方法來實現原同步方法的非同步搜悶森調用 如 FileStream 類提供了 BeginRead 和 EndRead 方法來從文件非同步讀取位元組 它們是 Read 方法的非同步版本
Begin 方法包含同步方法簽名中的任何參數 此外還包含另外兩個參數 一個AsyncCallback 委託和一個用戶定義的狀態對象 委託用來調用回調方法 狀態對象是用來向回調方法傳遞狀態信息 該方法返回一個實現 IAsyncResult 介面的對象
End 方法用於結束非同步操作並返回結果 因此包含同步方法簽名中的 ref 和 out 參數 返回值類型也與同步方法相同 該方法還包括一個 IAsyncResult 參數 用於獲取非同步操作是否完成的信息 當然在使用時就必須傳入對應的 Begin 方法返回的對象實例
開始非同步操作後如果要阻止應用程序 可以直接調用 End 方法 這會阻止應用程序直到非同步操作完成後再繼續執行 也可以使用 IAsyncResult 的 AsyncWaitHandle 屬性 調用其中的WaitOne等方法來阻塞線程 這兩種方法的區別不大 只是前者必須一直等待而後者可以設置等待超時
如果不阻止應用程序 則可以通過輪循 IAsyncResult 的 IsCompleted 狀態來判斷操作是否完成 或使用 AsyncCallback 委託來結束非同步操作 AsyncCallback 委託包含一個 IAsyncResult 的簽名 回調方法內部再調用 End 方法來獲取操作執行結果
代碼罩者
C#非同步編程模式IAsyncResult之IAsyncResult 介面
public interface IAsyncResult
{
object AsyncState { get; }
WaitHandle AsyncWaitHandle { get; }
bool CompletedSynchronously { get; }
bool IsCompleted { get; }
}
我用一個 AsyncDemo 類作為非同步方法的提供者 後面的程序都會調用它 內部很簡單 構造函數接收一個字元串作為 name Run 方法輸出 My name is + name 而非同步方法直接用委託的 BeginInvoke 和 EndInvoke 方法實現
public class AsyncDemo
{
// Use in asynchronous methods
private delegate string runDelegate();
private string m_Name;
private runDelegate m_Delegate;
public AsyncDemo(string name)
{
m_Name = name;
m_Delegate = new runDelegate(Run);
}
/**//// ﹤summary﹥
/// Synchronous method
/// ﹤/summary﹥世畝
/// ﹤returns﹥﹤/returns﹥
public string Run()
{
return My name is + m_Name;
}
/**//// ﹤summary﹥
/// Asynchronous begin method
/// ﹤/summary﹥
/// ﹤param name= callBack ﹥﹤/param﹥
/// ﹤param name= stateObject ﹥﹤/param﹥
/// ﹤returns﹥﹤/returns﹥
public IAsyncResult BeginRun(
AsyncCallback callBack Object stateObject)
{
try
{
return m_Delegate BeginInvoke(callBack stateObject);
}
catch(Exception e)
{
// Hide inside method invoking stack
throw e;
}
}
/**//// ﹤summary﹥
/// Asynchronous end method
/// ﹤/summary﹥
/// ﹤param name= ar ﹥﹤/param﹥
/// ﹤returns﹥﹤/returns﹥
public string EndRun(IAsyncResult ar)
{
if (ar == null)
throw new NullReferenceException(
Arggument ar can t be null );
try
{
return m_Delegate EndInvoke(ar);
}
catch (Exception e)
{
// Hide inside method invoking stack
throw e;
}
}
}
C#非同步編程模式IAsyncResult操作步驟 首先是 Begin 之後直接調用 End 方法 當然中間也可以做其他的操作
class AsyncTest
{
static void Main(string[] args)
{
AsyncDemo demo = new AsyncDemo( jiangnii );
// Execute begin method
IAsyncResult ar = demo BeginRun(null null);
// You can do other things here
// Use end method to block thread
// until the operation is plete
string demoName = demo EndRun(ar);
Console WriteLine(demoName);
}
}
也可以用 IAsyncResult 的 AsyncWaitHandle 屬性 我在這里設置為 秒超時
class AsyncTest
{
static void Main(string[] args)
{
AsyncDemo demo = new AsyncDemo( jiangnii );
// Execute begin method
IAsyncResult ar = demo BeginRun(null null);
// You can do other things here
// Use AsyncWaitHandle WaitOne method to block thread for second at most
ar AsyncWaitHandle WaitOne( false);
if (ar IsCompleted)
{
// Still need use end method to get result
// but this time it will return immediately
string demoName = demo EndRun(ar);
Console WriteLine(demoName);
}
else
{
Console WriteLine( Sorry
can t get demoName the time is over );
}
}
}
C#非同步編程模式IAsyncResult要注意的還有 不中斷的循環 每次循環輸出一個
class AsyncTest
{
static void Main(string[] args)
{
AsyncDemo demo = new AsyncDemo( jiangnii );
// Execute begin method
IAsyncResult ar = demo BeginRun(null null);
Console Write( Waiting );
while (!ar IsCompleted)
{
Console Write( );
// You can do other things here
}
Console WriteLine();
// Still need use end method to get result
//but this time it will return immediately
string demoName = demo EndRun(ar);
Console WriteLine(demoName);
}
}
最後是使用回調方法並加上狀態對象 狀態對象被作為 IAsyncResult 參數的 AsyncState 屬性被傳給回調方法 回調方法執行前不能讓主線程退出 我這里只是簡單的讓其休眠了 秒 另一個與之前不同的地方是 AsyncDemo 對象被定義成了類的靜態欄位 以便回調方法使用
class AsyncTest
{
static AsyncDemo demo = new AsyncDemo( jiangnii );
static void Main(string[] args)
{
// State object
bool state = false;
// Execute begin method
IAsyncResult ar = demo BeginRun(
new AsyncCallback(outPut) state);
// You can do other thins here
// Wait until callback finished
System Threading Thread Sleep( );
}
// Callback method
static void outPut(IAsyncResult ar)
{
bool state = (bool)ar AsyncState;
string demoName = demo EndRun(ar);
if (state)
{
Console WriteLine(demoName);
}
else
{
Console WriteLine(demoName + isn t it? );
}
}
}
C#非同步編程模式IAsyncResult的後話
對於一個已經實現了 BeginOperationName 和 EndOperationName方法的對象 我們可以直接用上述方式調用 但對於只有同步方法的對象 我們要對其進行非同步調用也不需要增加對應的非同步方法 而只需定義一個委託並使用其 BeginInvoke 和 EndInvoke 方法就可以了
lishixin/Article/program/net/201311/11864
❺ 前端必學-函數式編程(六)
我們前篇談了很多關於【閉包】的理解了,所以你應該會知道,我們現在將要談的就是 ——【非同步】。
我們為什麼覺得「非同步問題」復雜呢?
其中很重要的一個原因是 —— 時間!時間將我們對數據的操判運作、管理,變復雜了好幾個量級!
(需要特別提出並明確的是: 非同步和同步之間是可以相互轉化的! 我們使用非同步或者同步取決於 —— 如何使代碼更加可讀!)
函數式編程給出了實現「代碼更可讀」的落地原則(已多次回顧):
所以我們可以期待,非同步在函數式編程中的表現!
上代碼:
onCustomer(..) 和 onOrders(..) 是兩個【回調函數】釋義,兩者執行的先後順序並不能確定,所以它是一個基於時間掘喚梁的復雜狀態。
釋義:回調函數其實就是一個參數,將這個函數作為參數傳到另一個函數裡面,當那個函數執行完之後,再執行傳進去的這個函數。
通常來說,我們最先想到的是:把 lookupOrders(..) 寫到 onCustomer(..) 裡面,那我們就可以確認 onOrders(..) 會在 onCustomer(..) 之後運行。
這樣寫,對嗎?
不對!因為 onCustomer(..) 、 onOrders(..) 這兩個回調函數的關系更像是一種競爭關系(都是賦值 customer.orders ), 它們應該並行執行 , 而不是串列執行 。
即:我不管你們誰先執行,誰先執行完,誰就賦值給 customer.orders !
那我們的思路應該是:
不過,這樣讓代碼又變得更加難閱讀!!函數內部賦值依賴於外部變數、甚至受外部回調函數的影響。
那究竟怎麼辦呢?
最終,我們借用 JS promise 減少這個時間狀態,將非同步轉成同步:
兩個 .then(..) 運行之前, lookupCustomer(..) 和 lookupOrders(..) 已被同步調用,滿足並行執行,誰先結束,誰賦值給 customer.orders ,所以我們不需要知道誰先誰後!
在這樣的實現下,不再需要時間先後的概念!減少了時間狀態!!代碼的可讀性更高了!!
這是一個 積極的數組 ,因為它們同步(即時)地操作著離散的即時值或值的列表/結構上的值。
什麼意思?
a 映射到 b,再去修改 a ,b 不會收到影響。
而這,是一個 惰性的數組 , mapLazy(..) 本質上 「監聽」 了數組 a,只要一個新的值添加到數組的末端(push(..)),它都會運行映射函數 v => v * 2 並把改變後的值添加到數組 b 里。
什麼意思?
a 映射到 b,再去修改 a ,b 也會修改。
原來,後者存在 非同步 的概念。
讓我們來想像這樣一個鏈櫻數組,它不只是簡單地獲得值,它還是一個懶惰地接受和響應(也就是「反應」)值的數組,比如:
設置「懶惰的數組」 a 的過程是非同步的!
b ,是 map 映射後的數組,但更重要的是,b 是 反應性 的,我們對 b 加了一個類似監聽器的東西。
這里直接給出解答:
這里再多小結一句:時間讓非同步更加復雜,函數式編程在非同步下的運用就是減少或直接幹掉時間狀態。
想像下 a 還可以被綁定上一些其他的事件上,比如說用戶的滑鼠點擊事件和鍵盤按鍵事件,服務端來的 websocket 消息等。
上述的 LazyArray 又可叫做 observable !(當然,它不止用在 map 方法中)
現在已經有各種各樣的 Observables 的庫類,最出名的是 RxJS 和 Most 。
以 RxJS 為例:
不僅如此,RxJS 還定義了超過 100 個可以在有新值添加時才觸發的方法。就像數組一樣。每個 Observable 的方法都會返回一個新的 Observable,意味著他們是鏈式的。如果一個方法被調用,則它的返回值應該由輸入的 Observable 去返回,然後觸發到輸出的 Observable里,否則拋棄。
比如:
本篇介紹了【非同步】在函數式編程中的表現。
原則是:對於那些非同步中有時態的操作,基礎的函數式編程原理就是將它們變為無時態的應用。即 減少時間狀態 !
就像 promise 創建了一個單一的未來值,我們可以創建一個積極的列表的值來代替像惰性的observable(事件)流的值。
我們介紹了 RxJS 庫,後續我們還會介紹更多優美的 JS 函數式編程庫!
(俗話說的好,三方庫選的好,下班都很早!!)
現在本瓜有點明白那句話了:看一門語言是不是函數式編程,取決於它的核心庫是不是函數式編程。
也許我們還不熟悉像 RxJS 這類庫,但我們慢慢就會越來越重視它們,越來越使用它們,越來越領會到它們!!
非同步,以上。
❻ 如何在一個類中實現非同步
開個線程池,為每個方法的執行分配一個線程,創建一個hashmap結果集,每個方法執行完,將其存入hashmap中,最後通過判斷hashmap的大小,判斷所有方法線程是否執行完畢,執行完畢則返回該hashmap。
非同步編程其實很常見,特別是在出線Node.js之後,非同步編程更是讓很多開發者受益。那麼回到最初的地方,傳統的前端開發中如何實現非同步編程呢?下面列舉了js實現非同步編程的四種方式。方法一:使用回調函數方法二:事件監聽可以定義一個事件,並為這個事件設定處理函數。這樣只有當這個時間發生的情況下,對應的處理函數才會被執行。方法三:事件的發布/訂閱這個模式在NodeJS以及其他JS框架中都有實現,是一個非常常用的非同步編程方式。
方法四:Promise模式ES6中提供了原生的Promise對象,這個模式最開始只是一個構想,後來由一些框架庫實現。Promise對象代表了未來才會知道結果的事件。Promise的基本思路就是,將需要非同步執行的事件儲存起來,然後根據非同步事件之行後的結果狀態執行下一步的操作。具體的Promise對象的原理和ES6中的使用方法將在下一篇文章中更加深入的進行介紹。
多線程實現。
過程如下
創建一下對象:
robot對象
avi保存對象
行走對象
在robot里使用多線程,2個線程就夠,1個執行avi保存對象,1個執行行走對象。
之所以要創建3個對象,主要是考慮到軟體工程的分而治之的思想。
另外如果你真是要製作機器人的話
可以做2個系統一個是運動控制系統,一個是avi存儲系統,系統間不互聯。這樣互相不會有干擾,而且容易實現,不會讓功能混亂。
❼ 下面哪些方法可以用作javascript非同步模式的編程
javascript語言是單線程機制。所謂單線程就是按次序執行,執行完一個任務再執行下一個。
對於瀏覽器來說,也就是無法在渲染頁面的同時執行代碼。
單線程機制的優點在於實現起來較為簡單,運行環境相對簡單。缺點在於,如果中間有任務需要響應時間過長,經常會導致
頁面載入錯誤或者瀏覽器無響應的狀況。這就是所謂的逗同步模式地,程序執行順序與任務排列順序一致。對於瀏覽器來說,
同步模式效率較低,耗時長的任務都應該使用非同步模式;而在伺服器端,非同步模式則是唯一的模式,如果採用同步模式個人認為
伺服器很快就會出現12306在高峰期的表現。。。。
非同步模式的四種方式:
1.回調函數callback
所謂回調函數,就是將函數作為參數傳到需要回調的函數內部再執行。
典型的例子就是發送ajax請求。例如:
$.ajax({
async: false,
cache: false,
dataType: 'json',
url: "url",
success: function(data) {
console.log('success');
},
error: function(data) {
console.log('error');
}
})
當發送ajax請求後,等待回應的過程不會堵塞程序運行,耗時的操作相當於延後執行。
回調函數的優點在於簡單,容易理解,但是可讀性較差,耦合度較高,不易於維護。
2.事件驅動
javascript可以稱之為是基於對象的語言,而基於對象的基本特徵就是事件驅動(Event-Driven)。
事件驅動,指的是由滑鼠和熱鍵的動作引發的一連串的程序操作。
例如,為頁面上的某個
$('#btn').onclick(function(){
console.log('click button');
});
綁定事件相當於在元素上進行監聽,是否執行注冊的事件代碼取決於事件是否發生。
優點在於容易理解,一個元素上可以綁定多個事件,有利於實現模塊化;但是缺點在於稱為事件驅動的模型後,流程不清晰。
3.發布/訂閱
發布訂閱模式(publish-subscribe pattern)又稱為觀察者模式(Observer pattern)。
該模式中,有兩類對象:觀察者和目標對象。目標對象中存在著一份觀察者的列表,當目標對象
的狀態發生改變時,主動通知觀察者,從而建立一種發布/訂閱的關系。
jquery有相關的插件,在這不是重點不細說了。。。。回頭寫個實現貼上來
4.promise模式
promise對象是CommonJS工作組提供的一種規范,用於非同步編程的統一介面。
promise對象通常實現一種then的方法,用來在注冊狀態發生改變時作為對應的回調函數。
promise模式在任何時刻都處於以下三種狀態之一:未完成(unfulfilled)、已完成(resolved)和拒絕(rejected)。以CommonJS
Promise/A
標准為例,promise對象上的then方法負責添加針對已完成和拒絕狀態下的處理函數。then方法會返回另一個promise對象,以便於形成promise管道,這種返回promise對象的方式能夠支持開發人員把非同步操作串聯起來,如then(resolvedHandler,
rejectedHandler); 。resolvedHandler
回調函數在promise對象進入完成狀態時會觸發,並傳遞結果;rejectedHandler函數會在拒絕狀態下調用。
Jquery在1.5的版本中引入了一個新的概念叫Deferred,就是CommonJS promise A標準的一種衍生。可以在jQuery中創建
$.Deferref的對象。同時也對發送ajax請求以及數據類型有了新的修改,參考JQuery API。
除了以上四種,javascript中還可以利用各種函數模擬非同步方式,更有詭異的諸如用同步調用非同步的case
只能用team里同事形容java和javascript的一句話作為結尾:
逗寫java像在高速路上開車,寫javascript像在草原上開車地-------------以此來形容javascript這種無類型的語言有多自由
but,如果草原上都是坑。
❽ python非同步有哪些方式
yield相當於return,他將相應的值返回給調用next()或者send()的調用者,從而交出了CPU使用權,而當調用者再次調用next()或者send()的時候,又會返回到yield中斷的地方,如果send有參數,還會將參數返回給yield賦值的變數,如果沒有就和next()一樣賦值為None。但是這里會遇到一個問題,就是嵌套使用generator時外層的generator需要寫大量代碼,看如下示例:
注意以下代碼均在Python3.6上運行調試
#!/usr/bin/env python# encoding:utf-8def inner_generator():
i = 0
while True:
i = yield i if i > 10: raise StopIterationdef outer_generator():
print("do something before yield")
from_inner = 0
from_outer = 1
g = inner_generator()
g.send(None) while 1: try:
from_inner = g.send(from_outer)
from_outer = yield from_inner except StopIteration: breakdef main():
g = outer_generator()
g.send(None)
i = 0
while 1: try:
i = g.send(i + 1)
print(i) except StopIteration: breakif __name__ == '__main__':
main()041
為了簡化,在Python3.3中引入了yield from
yield from
使用yield from有兩個好處,
1、可以將main中send的參數一直返回給最里層的generator,
2、同時我們也不需要再使用while循環和send (), next()來進行迭代。
我們可以將上邊的代碼修改如下:
def inner_generator():
i = 0
while True:
i = yield i if i > 10: raise StopIterationdef outer_generator():
print("do something before coroutine start") yield from inner_generator()def main():
g = outer_generator()
g.send(None)
i = 0
while 1: try:
i = g.send(i + 1)
print(i) except StopIteration: breakif __name__ == '__main__':
main()
執行結果如下:
do something before coroutine start123456789101234567891011
這里inner_generator()中執行的代碼片段我們實際就可以認為是協程,所以總的來說邏輯圖如下:
我們都知道Python由於GIL(Global Interpreter Lock)原因,其線程效率並不高,並且在*nix系統中,創建線程的開銷並不比進程小,因此在並發操作時,多線程的效率還是受到了很大制約的。所以後來人們發現通過yield來中斷代碼片段的執行,同時交出了cpu的使用權,於是協程的概念產生了。在Python3.4正式引入了協程的概念,代碼示例如下:
import asyncio# Borrowed from http://curio.readthedocs.org/en/latest/[email protected] countdown(number, n):
while n > 0:
print('T-minus', n, '({})'.format(number)) yield from asyncio.sleep(1)
n -= 1loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(countdown("A", 2)),
asyncio.ensure_future(countdown("B", 3))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()12345678910111213141516
示例顯示了在Python3.4引入兩個重要概念協程和事件循環,
通過修飾符@asyncio.coroutine定義了一個協程,而通過event loop來執行tasks中所有的協程任務。之後在Python3.5引入了新的async & await語法,從而有了原生協程的概念。
async & await
在Python3.5中,引入了aync&await 語法結構,通過」aync def」可以定義一個協程代碼片段,作用類似於Python3.4中的@asyncio.coroutine修飾符,而await則相當於」yield from」。
先來看一段代碼,這個是我剛開始使用async&await語法時,寫的一段小程序。
#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time
async def wait_download(url):
response = await requets.get(url)
print("get {} response complete.".format(url))
async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in {} seconds".format(end - start))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
這里會收到這樣的報錯:
Task exception was never retrieved
future: <Task finished coro=<wait_download() done, defined at asynctest.py:9> exception=TypeError("object Response can't be used in 'await' expression",)>
Traceback (most recent call last):
File "asynctest.py", line 10, in wait_download
data = await requests.get(url)
TypeError: object Response can't be used in 'await' expression123456
這是由於requests.get()函數返回的Response對象不能用於await表達式,可是如果不能用於await,還怎麼樣來實現非同步呢?
原來Python的await表達式是類似於」yield from」的東西,但是await會去做參數檢查,它要求await表達式中的對象必須是awaitable的,那啥是awaitable呢? awaitable對象必須滿足如下條件中其中之一:
1、A native coroutine object returned from a native coroutine function .
原生協程對象
2、A generator-based coroutine object returned from a function decorated with types.coroutine() .
types.coroutine()修飾的基於生成器的協程對象,注意不是Python3.4中asyncio.coroutine
3、An object with an await method returning an iterator.
實現了await method,並在其中返回了iterator的對象
根據這些條件定義,我們可以修改代碼如下:
#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time
async def download(url): # 通過async def定義的函數是原生的協程對象
response = requests.get(url)
print(response.text)
async def wait_download(url):
await download(url) # 這里download(url)就是一個原生的協程對象
print("get {} data complete.".format(url))
async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in {} seconds".format(end - start))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())27282930
好了現在一個真正的實現了非同步編程的小程序終於誕生了。
而目前更牛逼的非同步是使用uvloop或者pyuv,這兩個最新的Python庫都是libuv實現的,可以提供更加高效的event loop。
uvloop和pyuv
pyuv實現了Python2.x和3.x,但是該項目在github上已經許久沒有更新了,不知道是否還有人在維護。
uvloop只實現了3.x, 但是該項目在github上始終活躍。
它們的使用也非常簡單,以uvloop為例,只需要添加以下代碼就可以了
import asyncioimport uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())123
❾ 如何寫一個「非同步函數」
我們平常編程寫的函數 幾乎都是同步調用函數,那麼我們如何寫一個非同步執行的函數呢?!我想這個問題也許是哪些比較喜歡專研的程序員或者具有專研精神的人士回提出的問題吧!我們很多人已經習慣了windows系統提供的一些非同步機制,使用這些非同步機制我們很快的就能實現一些非同步操作甚至可以很容易的實現一個非同步執行的函數;但是我們研究過實現一個「非同步函數」的本質嗎?! 在單線程的系統中,所以的指令執行都是順序執行的,這就暗示了如果一個函數A中調用了函數B,則A必須等到B執行後才能繼續執行A中剩下的代碼。 在多線程中,如果我們有一個threadA線程,在該線程中調用了一個函數C,而該C函數我們想將它實現成非同步執行的,而非同步執行必須要有多線程支持;如果我們在Windows中編寫程序,創建一個線程是很簡單只要使用 HANDLE WINAPI CreateThread( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId); 函數就可以創建一個線搭旁程。 那麼我悉並們按如下方式可以實現一個非同步的FuncC函數: (1)先把你要非同步完成的工作單獨寫成要給函數,如 DWORD WINAPI AsyncronousThread( LPVOID lpParameter // thread data){ .....}(2)在函數FuncC中使用CreateThtread函數將(1)中的函數創睜枝跡建一成一個線程,然後直接返回。 CreateThread(....,AsyncronousThread,...);return;}當然,寫一個非同步函數的方法很多,但是一個本質不會變,就是必須要依據多線程才能實現。