-
Notifications
You must be signed in to change notification settings - Fork 0
会出现无法结束的情况,频率不是很高,但是也不低,十次可能就出现一次 #1
Comments
原来的实现有bug,会导致卡死的情况出现 jmjoy/async-wg#1
有没有什么例子可以重现吗? |
start_wg2 wait group polled. |
@nkbai 代码示例有吗? |
关键在main函数中, |
@nkbai 现在master的代码呢? |
我自己重新实现了一个简单的wait group,完全没有按照你的思路来,所以就没问题了 |
闲逛无意间看了下源码,api没设计好。其中的一点是没借用RIIA,这很可能也是导致上面的代码失败的原因。 use async_std::prelude::*;
use async_std::task;
use async_wg::WaitGroup;
use std::time::Duration;
fn main() {
task::block_on( async {
let wg = WaitGroup::new();
for _ in 0..10isize {
let mut wg = wg.clone();
// Add count n.
wg.add(1isize).await;
let fut = async move {
println!("sleeping");
task::sleep(Duration::from_secs(4)).await; // 到这个await可以退出
println!("never printed"); // 这里不执行,不会打印
wg.done().await; // 这里也就不会调用
};
task::spawn(fut.race(task::sleep(Duration::from_secs(1)))); // 等待1秒钟结束,比上面的fut更早结束, 如果改成大于4秒的话,就能正常结束。
}
// Wait for done count is equal to add count.
wg.await;
});
} 当然 PR #2 重写的实现由于api没变自然也一样会有这种问题。 |
@laizy 谢谢大佬指点。 |
@laizy 你说的这个应该是完全不同的两个问题 如果没有调用done,导致await不返回,这个就是api设计的效果。 https://gobyexample.com/waitgroups 看我理解的不对 |
@nkbai Golang必须要defer确保Done执行了,Rust则需要在drop里面确定Done,这样的话,async/await就没法用了,参考crossbeam的WaitGroup。 我在想这个库是不是得archive掉。 |
@jmjoy 👍 |
错了,你需要好好理理这里的本质问题。即便是调用done,也一样会导致卡死。我上面的例子只是为了方便重现。
|
什么情况下会同时调用done而导致无法拿到内部的锁呢? 如果count和waker不是同一把锁,会出现如下情况
|
实现了一个lock-free的版本供你们参考:https://github.com/laizy/waitgroup-rs |
下面是我的实现:
做了一下修改:
出现了这种情况:
关于 tokio我还不是特别熟悉,需要探索为什么会出现这种情况。
我修改代码直接用你原始的版本,仍然会出现卡主(wg.await不返回),无法结束的情况
The text was updated successfully, but these errors were encountered: