原文
import std.stdio;
import std.concurrency;
import std.algorithm;
import std.range;
import std.exception;
import std.format;
import core.thread;
struct Progress {
Tid tid; // 报告线程的标识
size_t amount; // 进度
size_t total; // 总进度
}
void display(Progress[Tid] progresses) {
const amount = progresses.byValue.map!(p => p.amount).sum;
const total = progresses.byValue.map!(p => p.total).sum;
writefln!"%6.2f%%"(100.0 * amount / total);
}
// 工作线程
void download(string url) {
writefln!"%s线程下载了%s."(thisTid, url);
enum total = 20;
foreach (i; 0 .. total) {
// 模仿进度
Thread.sleep(100.msecs);
// 报告进度至所有者
ownerTid.send(Progress(thisTid, i + 1, total));
}
}
void main() {
auto list = [ "dlang.org", "ddili.org" ];
auto downloaders = list.length.iota
.map!(i => spawnLinked(&download, list[i])).array;
Progress[Tid] progresses;
size_t finished = 0;
while (finished != list.length) {
receive(
(LinkTerminated arg) {
++finished;
// 是否退出
enforce((arg.tid in progresses) &&
(progresses[arg.tid].amount == progresses[arg.tid].total),
format!"%s线程意外退出"(arg.tid));
},
(Progress progress) {
progresses[progress.tid] = progress;
progresses.display();
}
);
}
writeln("处理下载文件");
}