gpt4 book ai didi

multithreading - Perl 6 可以遵守多少 promise ?

转载 作者:行者123 更新时间:2023-12-03 22:40:35 25 4
gpt4 key购买 nike

这是一个有点花言巧语的标题,但在玩弄Promises我想看看我能把这个想法延伸到什么程度。在这个程序中,我这样做是为了可以指定我想要做出多少 promise 。

  • 线程调度器中的默认值为 16 个线程 ( rakudo/ThreadPoolScheduler.pm )
  • 如果我指定的数量超过这个数字,程序就会挂起,但我不会收到警告(比如“线程太多”)。
  • 如果我设置 RAKUDO_MAX_THREADS,我可以停止程序挂起,但最终有太多线程竞争无法运行。

  • 我有两个问题,真的。
  • 程序如何知道它可以创建多少个线程?这比 promise 的数量略多,这是值得的。
  • 即使我可以制作更多线程,我怎么知道我应该允许多少线程?

  • 这是 Rakudo 2017.01 在我的 4 核小型 Macbook Air 上:
    my $threads = @*ARGS[0] // %*ENV<RAKUDO_MAX_THREADS> // 1;
    put "There are $threads threads";

    my $channel = Channel.new;

    # start some promises
    my @promises;
    for 1 .. $threads {
    @promises.push: start {
    react {
    whenever $channel -> $i {
    say "Thread {$*THREAD.id} got $i";
    }
    }
    }
    }
    put "Done making threads";

    for ^100 { $channel.send( $_ ) }
    put "Done sending";

    $channel.close;

    await |@promises;

    put "Done!";

    最佳答案

    这实际上不是关于 Promise本身,而是关于线程池调度程序。一个 Promise本身只是一个同步构造。 start构造实际上做了两件事:

  • 保证新鲜 $_ , $/ , 和 $!块内
  • 电话 Promise.start与那个块

  • Promise.start还做两件事:
  • 创建并返回 Promise
  • 调度block中的代码在线程池上运行,安排成功完成保持Promise并且异常中断了 Promise .

  • 拥有 Promise 不仅是可能的,而且也比较常见。不受线程池上代码支持的对象。 Promise.in , Promise.anyofPromise.allof工厂不会立即安排任何事情,而且还有各种用途 Promise涉及做 Promise.new然后拨打 keepbreak稍后的。所以我可以轻松创建和 await上 1000 Promise s:
    my @p = Promise.new xx 1000;
    start { sleep 1; .keep for @p };
    await @p;
    say 'done' # completes, no trouble

    同样,一个 Promise不是唯一可以在 ThreadPoolScheduler 上调度代码的东西.返回的许多东西 Supply (比如间隔、文件监视、异步套接字、异步进程)也都在那里安排他们的回调。可以通过执行 $*SCHEDULER.cue: { ... } 将代码扔到即发即忘的风格(虽然你经常关心结果或任何错误,所以它并不特别常见)。

    当前的 Perl 6 线程池调度程序有一个可配置但强制执行的上限,默认为 16 个线程。如果造成16个都被占用却无法取得进展的情况,而唯一能够取得进展的东西卡在工作队列中,那么就会发生死锁。这不是 Perl 6 线程池独有的;任何有界池都容易受到此影响(任何无界池都容易耗尽所有资源并导致进程被终止:-))。

    正如在另一篇文章中提到的,Perl 6.d 将生成 awaitreact非阻塞结构;这一直是计划,但没有足够的开发资源来及时实现 Perl 6.c。 use v6.d.PREVIEW pragma 提供了对该功能的早期访问。 (另外,公平警告,这是一项正在进行的工作。)结果是 awaitreact在线程池拥有的线程上将暂停计划代码的执行(对于那些好奇的人,通过继续)并允许线程继续执行进一步的工作。当等待的事情完成时,将安排代码的恢复,或者 react块获取 done .请注意,这意味着您可以在 await 之前和之后处于不同的操作系统线程上。或 react在 6.d. (大多数 Perl 6 用户不需要关心这一点。它主要与那些编写 C 库绑定(bind)或处理系统相关的东西相关。一个好的 C 库绑定(bind)将使绑定(bind)的用户没有关心。)

    即将到来的 6.d 更改并没有消除耗尽线程池的可能性,但这意味着您在 6.c 中可以做的一堆方法将不再受到关注(注意,编写递归征服/划分事物 await 分割部分的结果,或者有数千个事件的 react 块以 start react { ... } 启动)。

    展望 future ,线程池调度器本身也将变得更加智能。接下来是推测,尽管考虑到我可能是实现更改的人,这可能是提供的最佳推测。 :-) 线程池将根据所取得的进展开始,并使用它来动态调整池大小。这将包括注意到没有取得任何进展,并结合观察到工作队列包含项目,添加线程以尝试解决死锁 - 以增加线程的内存开销为代价。今天,无论如何,线程池都会保守地产生到其最大大小,即使这不是一个特别好的选择;很可能会使用某种爬山算法来尝试并确定一个最佳数字。一旦发生这种情况,默认的 max_threads 可以大幅提高,这样更多的程序将 - 以大量内存开销为代价 - 能够完成,但大多数程序将仅使用少数线程运行。

    关于multithreading - Perl 6 可以遵守多少 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43449883/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com