
- D 程式設計基礎
- D 程式設計 - 首頁
- D 程式設計 - 概述
- D 程式設計 - 環境
- D 程式設計 - 基本語法
- D 程式設計 - 變數
- D 程式設計 - 資料型別
- D 程式設計 - 列舉
- D 程式設計 - 字面量
- D 程式設計 - 運算子
- D 程式設計 - 迴圈
- D 程式設計 - 條件語句
- D 程式設計 - 函式
- D 程式設計 - 字元
- D 程式設計 - 字串
- D 程式設計 - 陣列
- D 程式設計 - 關聯陣列
- D 程式設計 - 指標
- D 程式設計 - 元組
- D 程式設計 - 結構體
- D 程式設計 - 聯合體
- D 程式設計 - 範圍
- D 程式設計 - 別名
- D 程式設計 - 混入
- D 程式設計 - 模組
- D 程式設計 - 模板
- D 程式設計 - 不可變
- D 程式設計 - 檔案 I/O
- D 程式設計 - 併發
- D 程式設計 - 異常處理
- D 程式設計 - 合約
- D - 條件編譯
- D 程式設計 - 面向物件
- D 程式設計 - 類與物件
- D 程式設計 - 繼承
- D 程式設計 - 過載
- D 程式設計 - 封裝
- D 程式設計 - 介面
- D 程式設計 - 抽象類
- D 程式設計 - 有用資源
- D 程式設計 - 快速指南
- D 程式設計 - 有用資源
- D 程式設計 - 討論
D 程式設計 - 併發
併發是指程式在同一時間內執行多個執行緒。一個併發程式的例子是 Web 伺服器同時響應多個客戶端。併發使用訊息傳遞很容易實現,但如果基於資料共享則非常難以編寫。
線上程之間傳遞的資料稱為訊息。訊息可以由任何型別和任意數量的變數組成。每個執行緒都有一個 ID,用於指定訊息的接收者。任何啟動另一個執行緒的執行緒都稱為新執行緒的所有者。
在 D 中啟動執行緒
函式 spawn()
以指標作為引數,並從該函式開始一個新執行緒。該函式執行的任何操作,包括它可能呼叫的其他函式,都將在新執行緒上執行。所有者和工作執行緒都分別開始執行,就像它們是獨立的程式一樣。
示例
import std.stdio; import std.stdio; import std.concurrency; import core.thread; void worker(int a) { foreach (i; 0 .. 4) { Thread.sleep(1); writeln("Worker Thread ",a + i); } } void main() { foreach (i; 1 .. 4) { Thread.sleep(2); writeln("Main Thread ",i); spawn(≈worker, i * 5); } writeln("main is done."); }
當以上程式碼編譯並執行時,它讀取上一節中建立的檔案併產生以下結果:
Main Thread 1 Worker Thread 5 Main Thread 2 Worker Thread 6 Worker Thread 10 Main Thread 3 main is done. Worker Thread 7 Worker Thread 11 Worker Thread 15 Worker Thread 8 Worker Thread 12 Worker Thread 16 Worker Thread 13 Worker Thread 17 Worker Thread 18
D 中的執行緒識別符號
在模組級別全域性可用的 thisTid
變數始終是當前執行緒的 ID。您也可以在呼叫 spawn
時接收執行緒 ID。下面顯示了一個示例。
示例
import std.stdio; import std.concurrency; void printTid(string tag) { writefln("%s: %s, address: %s", tag, thisTid, &thisTid); } void worker() { printTid("Worker"); } void main() { Tid myWorker = spawn(&worker); printTid("Owner "); writeln(myWorker); }
當以上程式碼編譯並執行時,它讀取上一節中建立的檔案併產生以下結果:
Owner : Tid(std.concurrency.MessageBox), address: 10C71A59C Worker: Tid(std.concurrency.MessageBox), address: 10C71A59C Tid(std.concurrency.MessageBox)
D 中的訊息傳遞
函式 send()
傳送訊息,函式 receiveOnly()
等待特定型別的訊息。還有其他名為 prioritySend()
、receive()
和 receiveTimeout()
的函式,稍後將解釋。
在下面的程式中,所有者向其工作執行緒傳送一個 int
型別的訊息,並等待來自工作執行緒的一個 double
型別的訊息。執行緒繼續來回傳送訊息,直到所有者傳送一個負數的 int
。下面顯示了一個示例。
示例
import std.stdio; import std.concurrency; import core.thread; import std.conv; void workerFunc(Tid tid) { int value = 0; while (value >= 0) { value = receiveOnly!int(); auto result = to!double(value) * 5; tid.send(result); } } void main() { Tid worker = spawn(&workerFunc,thisTid); foreach (value; 5 .. 10) { worker.send(value); auto result = receiveOnly!double(); writefln("sent: %s, received: %s", value, result); } worker.send(-1); }
當以上程式碼編譯並執行時,它讀取上一節中建立的檔案併產生以下結果:
sent: 5, received: 25 sent: 6, received: 30 sent: 7, received: 35 sent: 8, received: 40 sent: 9, received: 45
D 中帶等待的訊息傳遞
下面顯示了一個帶等待的訊息傳遞的簡單示例。
import std.stdio; import std.concurrency; import core.thread; import std.conv; void workerFunc(Tid tid) { Thread.sleep(dur!("msecs")( 500 ),); tid.send("hello"); } void main() { spawn(&workerFunc,thisTid); writeln("Waiting for a message"); bool received = false; while (!received) { received = receiveTimeout(dur!("msecs")( 100 ), (string message) { writeln("received: ", message); }); if (!received) { writeln("... no message yet"); } } }
當以上程式碼編譯並執行時,它讀取上一節中建立的檔案併產生以下結果:
Waiting for a message ... no message yet ... no message yet ... no message yet ... no message yet received: hello
廣告