gpt4 book ai didi

c++ - 程序中止挂起命名的互斥量

转载 作者:行者123 更新时间:2023-11-27 23:40:09 24 4
gpt4 key购买 nike

我有几个进程,但当时应该只有一个在运行。这意味着假设 Process1 正在运行,如果 Process2 启动,则 Process2 应该等到 Process1做完了。为此,我正在考虑 boost named_mutex。为了避免在抛出某些异常时可能无法释放互斥量的情况,boost::lock_guard 看起来很有用。我想出了以下代码的简化版本。

#include <iostream>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/thread.hpp>
#include <chrono>
#include <thread>

using namespace boost::interprocess;
#pragma warning(disable: 4996)
int main()
{


std::cout << "Before taking lock" << std::endl;

named_mutex mutex(open_or_create, "some_name");
boost::lock_guard<named_mutex> guard(mutex) ;

// Some work that is simulated by sleep
std::cout << "now wait for 10 second" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));

std::cout << "Hello World";


}

到目前为止,还不错。当这个程序运行时,我按 Ctl+C 使程序中止(模拟程序崩溃、未处理的异常等)。之后,当我运行应用程序时,程序会卡在以下代码行。

named_mutex mutex(open_or_create, "some_name");
boost::lock_guard<named_mutex> guard(mutex) ;

如果我更改互斥量名称,那么它可以正常工作而不会被挂起。但是,看起来名为 some_name 的互斥量在某种不良状态下以某种方式“记住”在机器上。这会导致任何试图获取名称为 some_name 的互斥锁的应用程序都卡在这行代码上。如果我将此互斥量名称更改为 some_name2,程序将再次正常运行。

  1. 有人可以解释导致此行为的原因吗?
  2. 如何重置这个特定互斥量的行为?
  3. 最重要的是,如何在实际应用中避免这种情况?

最佳答案

this answer 中所述至 the question linked by @ppetraki aboveboost::interprocess:named_mutex,不幸的是,在 Windows 上使用文件锁而不是实际的互斥锁。如果您的应用程序异常终止,则该文件锁不会从系统中删除。这实际上是主题 to an open issue .

查看the source code ,我们看到,如果定义了 BOOST_INTERPROCESS_USE_WINDOWSinternal_mutex_type 映射到 windows_named_mutex,在内部,uses a windows_named_sync ,这seems to just be using a file lock到底。我不确定这种选择实现的理由究竟是什么。不管它是什么,似乎没有任何方法可以让 boost::interprocess 在 Windows 上使用正确命名的互斥体。我建议使用 CreateMutex 自己简单地创建一个命名的互斥体。 ,例如:

#include <type_traits>
#include <memory>
#include <stdexcept>
#include <mutex>
#include <iostream>

#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

struct CloseHandleDeleter { void operator ()(HANDLE h) const { CloseHandle(h); } };

class NamedMutex
{
std::unique_ptr<std::remove_pointer_t<HANDLE>, CloseHandleDeleter> m;

public:
NamedMutex(const wchar_t* name)
: m(CreateMutexW(nullptr, FALSE, name))
{
if (!m)
throw std::runtime_error("failed to create mutex");
}

void lock()
{
if (WaitForSingleObject(m.get(), INFINITE) == WAIT_FAILED)
throw std::runtime_error("something bad happened");
}

void unlock()
{
ReleaseMutex(m.get());
}
};

int main()
{
try
{
NamedMutex mutex(L"blub");

std::lock_guard lock(mutex);

std::cout << "Hello, World!" << std::endl;
}
catch (...)
{
std::cerr << "something went wrong\n";
return -1;
}

return 0;
}

关于c++ - 程序中止挂起命名的互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55821063/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com