【发布时间】:2015-03-15 12:32:21
【问题描述】:
我刚刚编译了一个我一直在 Windows for Linux 下工作的项目,发现它在某个时刻挂起。由于我使用的是 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 上有什么特别需要注意的地方? (编译器标志等)对我来说,这看起来好像异步调用是同步的,因此会导致死锁。但是为什么会这样
【问题讨论】:
-
您使用的是哪个编译器?也许不相关,但
std::async()返回的未来会在销毁时加入,因此如果您的库实现符合要求,则此调用将同步执行:std::async(std::launch::async, &BorderExtractor::preprocessImage, this, settings)。 AFAIK 在 MS 的实现中,未来的析构函数不会加入。 -
我正在使用 GCC。好的,我看到了问题。除了创建一个成员变量来拯救未来,还有什么办法吗?
-
你也在 Windows 上使用 GCC 吗?
-
不,我在那里使用 VS2013 编译器。
-
好的,那么情况就清楚了。详情见我的回答。
标签: c++ linux asynchronous mutex deadlock