Multithreading 如何在rust中传播来自多个线程的错误?
在防锈应用中,即:Multithreading 如何在rust中传播来自多个线程的错误?,multithreading,logging,error-handling,rust,Multithreading,Logging,Error Handling,Rust,在防锈应用中,即: 不使用“异步”的意义上的同步 使用std::thread的多线程 线程通过通道进行通信 “无论如何”板条箱用于注释和传播结果 我正在将所有错误传播到主线程,但我只看到主线程命中的错误。这通常发生在我加入子线程之前,所以我看不到真正的根本原因 为了查看多个线程的错误,我可以对样板文件进行什么最小程度的修改 (我会在答案中提出一些想法,但我希望有更好的方法。)一个选择是升级整个应用程序,使用日志框架,然后浏览日志 如果已添加Anyway.context(),请确保!,或者保释
- 不使用“异步”的意义上的同步
- 使用std::thread的多线程
- 线程通过通道进行通信
- “无论如何”板条箱用于注释和传播结果
(我会在答案中提出一些想法,但我希望有更好的方法。)一个选择是升级整个应用程序,使用日志框架,然后浏览日志 如果已添加Anyway.context(),请确保!,或者保释!注释,以便有条件地也引发记录器错误
最终,我会希望日志记录/遥测和从传播结果中清除数据,但即使如此,我也不希望为每一个容易出错的函数调用提供几行样板文件。我可以只使用主线程来监督子线程,在加入它们时将它们的所有结果聚合到某种Vec中,并对其进行过滤,并编写自定义代码来打印它
这仍然让人觉得需要做更多的工作;我不是第一个编写处理错误的线程生锈应用程序的人。我可能会让线程恐慌并“传播恐慌”: 但这是丑陋的:
- 它引入了子线程与主线程中错误处理方式的差异
- 在我的原始代码中的每个容易出错的调用站点,我都必须添加.unwrap()
- 如果我展开子线程中的每个错误,我甚至可能不使用结果错误处理,因为一切都将返回Ok()或恐慌。如果我进行了这种转换,那么我将更改所有现有函数的签名,这也是非常糟糕的
连接将返回结果
。更新:我找到了Vec.collect(),但这只返回第一个错误。如果我理解正确,同样的事情会阻止我将Result::and()和Result:and_链接起来。@masklin事实上我在主线程中做了更多的工作,因为我认为没有理由不这样做,但为了统一起见,我也可以将其移动到子线程中,并将其声明为主管paten。但是,我仍然不知道如何干净地连接所有线程。是collect()
-ing到结果只返回第一个失败。然后,和{u
将重点放在“成功路径”上,对于您想要的“失败路径”或{u else
,但在这种情况下,它并不是真正有用的:您需要一个合成路径作为所有失败的收集器。只需在子线程上迭代并将Err
值放入vec中(如果希望保留panic
错误和返回值errs,可能需要进行一些转换)。这听起来不错,拥有一个主管线程和一组工作线程是这类事情的标准模式。让主管也当工人听起来非常奇怪。您可以在收集过程中进行聚合,只需在收集的输出中不添加Ok(Ok())
信息,如果结果集为非空,则至少有一个线程失败。至于“打印自定义代码”,那几乎就是print!(“{:?}”,错误)
。