並行性是使程式在同一時間執行一個以上的執行緒。並行程式的一個例子是在Web伺服器響應多個用戶端在同一時間。並行是容易與訊息傳遞卻很難,如果它們是基於資料共用的寫入。
傳遞執行緒之間的資料被稱為訊息。訊息可以由任何型別和任意數量的變數。每個執行緒都有一個ID,它是用於指定郵件的收件人。即啟動另一個執行緒的任何執行緒被稱為新執行緒的所有者。即啟動另一個執行緒的任何執行緒被稱為新執行緒的所有者。
spawn() 接受一個函式指標作為引數,並從該函式啟動一個新執行緒。正在開展的功能,包括它可能呼叫其他函式的任何操作,將在新的執行緒中執行。owner和worker開始獨立執行的,好像他們是獨立的程式:
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
thisTid變數是全域性可用在模組級始終是當前執行緒的id。也可以收到重生時被呼叫threadid。一個例子如下所示。
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)
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
一個簡單的例子與傳遞與等待訊息如下所示。
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