该程序创建一个线程,用dir()读取目录,并将文件放在通道上$N个工作线程读取该通道并“处理”(打印)文件。
然而,我得到了这个“等待的第一个操作:”错误。
关于这个错误,我已经在陷阱页面上读了好几遍了,但还是没有弄明白。能解释一下这里发生了什么吗?
目录内容:
$ ls a b c traverse-dir0.p6
运行程序:
$ ./traverse-dir0.p6 traverse-dir0.p6 a b c An operation first awaited: in sub MAIN at ./traverse-dir0.p6 line 24 in block at ./traverse-dir0.p6 line 5 Died with the exception: Cannot find method 'path': no method cache and no .^find_method in block at ./traverse-dir0.p6 line 16
程序travers-dir. p6:
#!/usr/bin/env perl6 # There is a thread to populate $dir-channel by reading filenames in a directory with dir() # and $N worker threads to read the filenames from the $dir-channel. sub MAIN( Str $dir = ".", Int :$N = 4 ) { my $dir-channel = Channel.new(); my $dir-read = start { $dir-channel.send( $_ ) for dir $dir; $dir-channel.close; } my @workers = (^$N).map: { start { while my $file = $dir-channel.receive() { say $file.path; } CATCH { when X::Channel::ReceiveOnClosed { .resume } } } } await $dir-read, @workers; }
首先,关于从wait
引发的异常的输出。当异步操作失败时,有两条有趣的信息:
第一条信息指示wait
的位置,堆栈跟踪与此相关。第二部分是关于wait
重新引发异常的原因,并指出需要解决的问题。
这种情况下的问题是path
方法被调用到没有一个对象的对象上。这要归功于。简历
,这毫无意义。引发异常,表示无法从通道接收值。恢复它只是意味着循环主体在$file
中运行一个未定义的值,它缺少一个path
方法并导致错误。(顺便说一句:是非常非常罕见的。简历
是正确的答案。)
对代码的最小修复是替换。使用
,当频道关闭时终止迭代:最后一个
继续
my @workers = (^$N).map: {
start {
while my $file = $dir-channel.receive() {
say $file.path;
CATCH {
when X::Channel::ReceiveOnClosed { last }
}
}
}
}
但是,将频道
强制为可编辑的Seq
要简单得多。当频道
关闭时,这会自动处理终止迭代的问题,因此不会出现异常:
my @workers = (^$N).map: {
start {
for $dir-channel.Seq -> $file {
say $file.path;
}
}
}
由于start
是一个语句前缀,这进一步缩短为:
my @workers = (^$N).map: {
start for $dir-channel.Seq -> $file {
say $file.path;
}
}
我知道这可能是一个更有趣的问题的简化版本,或者可能是为了探索各种Perl 6并发性概念而做的,但是所有这些都可以替换为:
sub MAIN( Str $dir = ".", Int :$N = 4 ) {
race for dir($dir).race(batch => 1, degree => $N) -> $file {
say $file.path;
}
}
它具有相同的语义学,但节省了启动和管理工人,同时仍然控制工人的数量,并确保文件在工人之间以相同的方式分发。
问题内容: 如何更改以下代码,以触发两个异步操作并有机会同时运行? 我需要做这样的事情吗? 问题答案: TL; DR 不要在获得承诺的问题中使用模式,而是分别等待它们;而是使用(至少现在): 虽然您的解决方案 确实 并行运行这两个操作,但如果两个诺言都被拒绝,它就无法正确处理拒绝。 细节: 您的解决方案并行运行它们,但始终等待第一个完成,然后再等待第二个。 如果您只想启动它们,并行运行它们,并获得
问题内容: 我如何更改以下代码,以触发两个异步操作并有机会同时运行? 我需要做这样的事情吗? 问题答案: TL; DR 不要在获得承诺的问题中使用模式,而是分别等待它们;而是使用(至少现在): 虽然您的解决方案确实并行运行这两个操作,但是如果两个诺言都被拒绝,它就无法正确处理拒绝。 细节: 您的解决方案并行运行它们,但始终等待第一个完成,然后再等待第二个。如果您只想启动它们,并行运行它们,并获得两
我可以让selenium webdriver“默认”等待它的每个操作执行吗?例如,设置任何“默认等待时间”,使其尝试每500毫秒点击每个元素10次?
我已经实现了一个线程池。现在,它的基本操作如下: 空初始化(布尔detached_threads); bool调度(ulux(*dispatch_fn)(ulux), ulux arg, boolfree_arg); void shut\u down(); 静态无效*execute_task(无效*arg); 现在我想添加等待()操作,它将由主线程调用,并等待线程池中的所有线程完成它们正在执行的任
启动C 20时,原子的操作有等待操作和通知操作。但我不知道它们到底是怎么工作的。cppreference说: 执行原子等待操作。表现为它重复执行以下步骤: 比较此的值表示形式- 这些函数保证仅在值发生更改时返回,即使底层实现错误地解除了阻塞。 我不太明白这两个部分是如何相互关联的。这是否意味着如果值没有更改,那么即使我使用了notify\u one()/方法,函数也不会返回?这意味着该操作在某种程
我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似