持續發燒,聊聊Dart語言的併發處理,能挑戰Go不?
前言
貌似關於Dart的文章沒流量啊,就算在小編關懷上了首頁,看得人還是很少的。
算了,今天持續發燒,再來寫寫如何使用 Dart 語言的併發操作。說起併發操作,玩 Go 的同學該笑了,這就是我們的看家本領啊。玩 PHP 的同學繼續看看,表示我們光看不說話。
程式碼演示之前,我們先假設一個場景。假設我有一些漂亮妹妹,他們要出門旅行了,旅行的時候會發照片給我。在這裡個過程中,程式碼需要做的事情:
接收請求
安排出行計劃,同時出行哦,不能有先後之分
他們各自出行,可以發照片給我
返回結果
這個過程中,我關心的是他們能不能處理好自己的事情,因為我妹妹太多了,如果都讓我幫他們,累死我也搞不定啊,我就幹兩件事,安排好出行計劃,最後收照片。
程式碼演示一下吧
import 'dart:io';
import 'dart:isolate';
main() async {
print(DateTime.now().toString() + ' 開始');
//這是一個接收埠,可以理解成我的手機
ReceivePort receivePort = new ReceivePort();
//安排三個妹妹出去旅行,讓她們牢記我的手機號
await Isolate.spawn(travelToBeijing, receivePort.sendPort);
await Isolate.spawn(travelToShanghai, receivePort.sendPort);
await Isolate.spawn(travelToGuangzhou, receivePort.sendPort);
//我就在手機上,等待他們的訊息
receivePort.listen((message) {
print(message);
});
print(DateTime.now().toString() + ' 結束');
}
void travelToBeijing(SendPort sendPort) {
sleep(Duration(seconds: 3));
sendPort.send(DateTime.now().toString() + ' 我是妹妹1,我在北京了');
}
void travelToShanghai(SendPort sendPort) {
sleep(Duration(seconds: 3));
sendPort.send(DateTime.now().toString() + ' 我是妹妹2,我在上海了');
}
void travelToGuangzhou(SendPort sendPort) {
sleep(Duration(seconds: 3));
sendPort.send(DateTime.now().toString() + ' 我是妹妹3,我在廣州了');
}
上面寫了那麼多,都是啥意思呢,我自己稍微解釋下上面的程式碼。
Dart 裡的併發,用到的是 Isolate 類。
Isolate 翻譯過來即是 隔離區, 是 Dart 實現併發的重要類。它併發的原理,既不是多程式,也不是多執行緒,你說類似於 Go 的協程吧,也不像。
真的很難定義它,期待對作業系統研究更深的同學來佈道,當然這不影響我們使用。
Isolate.spawn 來定義一個併發任務,接收兩個引數,第一個是該任務的處理函式,第二個是該處理函式的所需要的引數
ReceivePort 翻譯一下 接收埠, 也可以翻譯成 接收器,用來接收各個任務回傳的訊息。
receivePort.listen 用來監聽各任務的回傳資訊,程式碼裡只是簡單列印
執行它,得到列印的結果
2021-07-01 15:40:38.132122 開始
2021-07-01 15:40:38.295683 結束
2021-07-01 15:40:41.200316 我是妹妹1,我在北京了
2021-07-01 15:40:41.248851 我是妹妹2,我在上海了
2021-07-01 15:40:41.296737 我是妹妹3,我在廣州了
注意看列印結果,妹妹們很乖,基本在同一時間給我回復了訊息。總共時間差不多3秒鐘,你可以新增更多工,都會是3秒鐘。
再次封裝一下
實際使用的時候,我們可以再次封裝,使用的同學不用去想 Isolate, ReceivePort 都是什麼鬼
import 'dart:io';
import 'dart:isolate';
class MultiTask {
static void run(
{List<TaskItem> taskList,
Function taskFunc,
Function onCompletedItem,
Function onCompletedAll}) async {
ReceivePort receivePort = new ReceivePort();
Map<String, Isolate> mapParam = {};
for (int i = 0; i < taskList.length; i++) {
TaskItem taskItem = taskList[i];
mapParam[taskItem.key] = await Isolate.spawn(
taskFunc, TaskMessage(receivePort.sendPort, taskItem));
}
List<TaskRes> taskResList = [];
receivePort.listen((message) async {
TaskRes taskRes = message as TaskRes;
if (null != onCompletedItem) await onCompletedItem(taskRes);
taskResList.add(taskRes);
mapParam[taskRes.key].kill();
if (taskResList.length == taskList.length) {
receivePort.close();
if (null != onCompletedAll) await onCompletedAll(taskResList);
}
});
}
}
class TaskMessage {
SendPort sendPort;
TaskItem taskItem;
TaskMessage(this.sendPort, this.taskItem);
}
class TaskItem {
String key;
String param;
TaskItem(this.key, this.param);
}
class TaskRes {
String key;
String res;
TaskRes(this.key, this.res);
}
使用的時候,這樣來:
import 'dart:io';
import 'dart:isolate';
import 'MultiTask.dart';
main() async {
List<TaskItem> taskList = [
TaskItem('1', 'param1'),
TaskItem('2', 'param2'),
TaskItem('3', 'param1'),
TaskItem('4', 'param2'),
TaskItem('5', 'param1'),
TaskItem('6', 'param2'),
TaskItem('7', 'param1'),
TaskItem('8', 'param2'),
TaskItem('9', 'param1'),
TaskItem('0', 'param2'),
];
print(DateTime.now());
MultiTask.run(
taskList: taskList,
taskFunc: taskFunc,
onCompletedItem: (TaskRes taskRes) =>
print(DateTime.now().toString() + '_' + taskRes.res),
onCompletedAll: (List<TaskRes> taskResList) =>
print(DateTime.now().toString() + '_onCompletedAll'),
);
}
void taskFunc(TaskMessage taskMessage) async {
sleep(Duration(seconds: 3));
String res = 'onCompletedItem is ok';
taskMessage.sendPort.send(TaskRes(taskMessage.taskItem.key, res));
}
走起來吧
2021-07-01 15:50:54.862973
2021-07-01 15:50:57.924675_onCompletedItem is ok
2021-07-01 15:50:57.954982_onCompletedItem is ok
2021-07-01 15:50:57.986042_onCompletedItem is ok
2021-07-01 15:50:58.021282_onCompletedItem is ok
2021-07-01 15:50:58.053387_onCompletedItem is ok
2021-07-01 15:50:58.088492_onCompletedItem is ok
2021-07-01 15:50:58.121968_onCompletedItem is ok
2021-07-01 15:50:58.157117_onCompletedItem is ok
2021-07-01 15:50:58.190835_onCompletedItem is ok
2021-07-01 15:50:58.229044_onCompletedItem is ok
2021-07-01 15:50:58.241011_onCompletedAll
可以看到,中間每一個任務完成的時間,都很接近,併發處理很完美
總結
當需要處理很多工時,可以開闢多個隔離區,併發執行,提高效率。
Dart語言對併發的處理,還算人性化,理解起來沒有難度,用起來也容易。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69999012/viewspace-2784258/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 持續發燒,試試Dart語言的非同步操作,效率提升500%Dart非同步
- GO語言併發Go
- Go語言專案實戰:併發爬蟲Go爬蟲
- 聊聊介面最大併發處理數
- 第09章 Go語言併發,Golang併發Golang
- Go併發呼叫的超時處理Go
- Go語言併發程式設計Go程式設計
- 十九、Go語言基礎之併發Go
- Go 併發 2.2:錯誤處理模式Go模式
- Go 語言異常處理Go
- GO 語言的併發模式你瞭解多少?Go模式
- Rill:Go語言中併發+事務的批處理開源專案Go
- GO 語言 Web 開發實戰一GoWeb
- Go語言 | CSP併發模型與Goroutine的基本使用Go模型
- Go 語言處理 yaml 檔案GoYAML
- 探索自然語言處理:語言模型的發展與應用自然語言處理模型
- 高併發實戰之冪等處理
- Go語言中的併發模式Go模式
- Go高效併發 11 | 併發模式:Go 語言中即學即用的高效併發模式Go模式
- 遊戲開發中的多語言處理遊戲開發
- Postgres併發處理
- MySQL 併發處理MySql
- Go 語言操作 MySQL 之 預處理GoMySql
- Go語言基礎-錯誤處理Go
- Go語言錯誤處理機制Go
- 有Go語言實戰培訓班嗎?go語言開發環境搭建Go開發環境
- 《快學 Go 語言》第 13 課 —— 併發與安全Go
- Go語言併發程式設計簡單入門Go程式設計
- Go語言 | 併發設計中的同步鎖與waitgroup用法GoAI
- Flutter開發之Dart語言基礎FlutterDart
- Go多協程併發環境下的錯誤處理Go
- 百度持續整合發展、挑戰與願景 - 董海煒
- go語言處理TCP拆包/粘包GoTCP
- 併發程式設計帶來的挑戰程式設計
- 處理併發衝突
- 《Go 語言併發之道》讀後感 - 第二章Go
- Go 為什麼不在語言層面支援 map 併發?Go
- 【Go 語言入門專欄】Go 語言的起源與發展Go