并发性是使程序在同一时间运行一个以上的线程。并发程序的一个例子是在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