- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我刚刚为 Linux 编译了一个我一直在 Windows 下工作的项目,发现它在某个点挂起。由于我使用 std::async 和 std::mutex 我的第一个假设是,这可能是一个死锁问题。但是,我想知道为什么它在 Windows 上运行良好。这是代码:
void BorderExtractor::preprocessImageAsync(const PreprocessingSettings& settings) {
_preprocessingMutex.lock();
if (!_preprocessingActive) {
_preprocessingActive = true;
std::async(std::launch::async, &BorderExtractor::preprocessImage, this, settings);
//this point is never reached on linux
_preprocessingUpToDate = true;
} else {
_cachedSettings = settings;
_preprocessingUpToDate = false;
}
_preprocessingMutex.unlock();
}
这是Linux下永不返回的函数。它一直运行到异步调用,然后才停止。它几乎看起来好像函数不是异步启动的,程序等待它返回,这是行不通的,因为另一个函数将尝试锁定同一个互斥量。
这是异步调用的函数:
void BorderExtractor::preprocessImage(PreprocessingSettings settings) {
//here some image processing stuff is done
_preprocessingMutex.lock();
//this point is never reached on linux
if (!_preprocessingUpToDate) {
_preprocessingUpToDate = true;
_preprocessingMutex.unlock();
std::async(std::launch::async, &BorderExtractor::preprocessImage, this, _cachedSettings);
} else {
_preprocessingUpToDate = true;
_preprocessingActive = false;
_preprocessingMutex.unlock();
}
}
在 linux 下永远不会达到它尝试锁定互斥锁之后的那个点。
现在,问题是什么?是我的代码有问题,还是在 Linux 上有什么特别需要注意的地方? (编译器标志等)对我来说,这似乎是异步调用是同步的,因此会导致死锁。但为什么会这样
最佳答案
这个调用:
async(std::launch::async, &BorderExtractor::preprocessImage, this, _cachedSettings);
有效地同步运行。这是因为 std::async()
返回的 std::future
的析构函数最终加入了异步计算 - 注意,行为如果你以其他方式获得 future ,那就不一样了。
因为你没有让 std::async
返回的 future 对象保持事件状态,它的生命周期在函数调用返回后立即结束,并且它的析构函数阻塞直到异步计算终止 - 这是永远的,因为这似乎会导致僵局。
这在 Windows 上工作的原因可能是因为您使用的是标准库的不兼容实现(例如 VS2013 附带的 Microsoft 实现),其中 future 的析构函数不加入异步计算 - MS 有意这样做,遵循 this (rejected) proposal by Herb Sutter 中说明的基本原理.
如果您正在寻找一种即发即弃的方法,请考虑 this alternative implementation of std::async()
,这不会导致返回的 future 阻止销毁(由 bamboon 提供):
template<class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type> async(
Function&& f,
Args&&... args)
{
using R = typename std::result_of<Function(Args...)>::type;
auto bound_task = std::bind(std::forward<Function>(f), std::forward<Args>(args)...);
auto task = std::packaged_task<R()>{std::move(bound_task)};
auto ret = task.get_future();
auto t = std::thread{std::move(task)};
t.detach();
return ret;
}
作为旁注,避免显式锁定/解锁互斥量。相反,使用 RAII 包装器,如 std::lock_guard
或(如有必要)std::unique_lock
以确保即使抛出异常或以防万一,你的互斥锁也会被解锁提前返回:
// The mutex will be unlocked automatically when the function returns.
std::lock_guard<std::mutex> lock{_preprocessingMutex};
if (!_preprocessingUpToDate) {
_preprocessingUpToDate = true;
async(std::launch::async, &BorderExtractor::preprocessImage, this, _cachedSettings);
// No need to call unlock() on the mutex!
} else {
_preprocessingUpToDate = true;
_preprocessingActive = false;
// No need to call unlock() on the mutex!
}
关于C++:std::async 和 std::mutex 在 Linux 上导致死锁但在 Windows 上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27991830/
我有带皮肤的 DNN。我的 head 标签有 runat="server"所以我尝试在 head 标签内添加一个标签 "> 在后面的代码中,我在属性中设置了 var GoogleAPIkey。问题是它
我在 Node.JS 中有一个导出模块 exports.doSomethingImportant= function(req, res) { var id = req.params.id; Demo.
我是 F# 的新手,我一直在阅读 F# for Fun and Profit。在为什么使用 F#? 系列中,有一个 post描述异步代码。我遇到了 Async.StartChild函数,我不明白为什么
File 中有一堆相当方便的方法类,如 ReadAll***/WriteAll***/AppendAll***。 我遇到过很多情况,当我需要它们的异步对应物时,但它们根本不存在。 为什么?有什么陷阱吗
我最近开始做一个 Node 项目,并且一直在使用 async 库。我有点困惑哪个选项会更快。在某些数据上使用 async.map 并获取其结果,或使用 async.each 迭代一组用户并将他们的相应
您好,我正在试用 Springs 异步执行器,发现您可以使用 @Async。我想知道是否有可能在 @Async 中使用 @Async,要求是需要将任务委托(delegate)给 @Async 方法在第
我需要支持取消一个函数,该函数返回一个可以在启动后取消的对象。在我的例子中,requester 类位于我无法修改的第 3 方库中。 actor MyActor { ... func d
假设 asyncSendMsg不返回任何内容,我想在另一个异步块中启动它,但不等待它完成,这之间有什么区别: async { //(...async stuff...) for msg
我想用 Mocha 测试异步代码. 我跟着这个教程testing-promises-with-mocha .最后,它说最好的方法是 async/await。 以下是我的代码,我打算将 setTimeo
正如我有限(甚至错误)的理解,Async.StartImmediate 和 Async.RunSynchronously 在当前线程上启动异步计算。那么这两个功能究竟有什么区别呢?谁能帮忙解释一下?
我有一行使用await fetch() 的代码。我正在使用一些调用 eval("await fetch ...etc...") 的脚本注入(inject),但问题是 await 在执行时不会执行从ev
我正在尝试使用 nodeJS 构建一个网络抓取工具,它在网站的 HTML 中搜索图像,缓存图像源 URL,然后搜索最大尺寸的图像。 我遇到的问题是 deliverLargestImage() 在循环遍
我想结合使用 async.each 和 async.series,但得到了意想不到的结果。 async.each([1, 2], function(item, nloop) { async.s
我的代码有问题吗?我使用 async.eachSeries 但我的结果总是抛出 undefined。 这里是我的代码: async.eachSeries([1,2,3], function(data,
我想在 trait 中编写异步函数,但是因为 async fn in traits 还不被支持,我试图找到等效的方法接口(interface)。这是我在 Rust nightly (2019-01-0
async setMyPhotos() { const newPhotos = await Promise.all(newPhotoPromises); someOtherPromise();
async.js 中 async.each 与 async.every 的区别?似乎两者都相同,只是 async.every 返回结果。纠正我,我错了。 最佳答案 每个异步 .each(coll, i
我正在尝试对一组项目运行 async.each。 对于每个项目,我想运行一个 async.waterfall。请参阅下面的代码。 var ids = [1, 2]; async.each(ids,
我的目标是测试 API 调用,将延迟考虑在内。我的灵感来自 this post . 我设计了一个沙箱,其中模拟 API 需要 1000 毫秒来响应和更改全局变量 result 的值。测试检查 500
async.each 是否作为异步数组迭代工作? async.eachSeries 是否作为同步数组迭代工作?(它实际上等待响应) 我问这些是因为两者都有回调,但 async.each 的工作方式类似
我是一名优秀的程序员,十分优秀!