d多生产单消费

原文

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("处理下载文件");
}
posted @ 2022-07-13 17:44  zjh6  阅读(33)  评论(0)    收藏  举报  来源