增强named_mutex和remove()命令
我有一个可以由多个线程创建的类。但在一个函数中,代码需要受到保护,因此我决定使用 boost 进程间互斥体。每个类都会在其构造函数中创建或打开相同的互斥锁:
MyClass::MyClass()
{
boost::interprocess::named_mutex m_Lock(
boost::interprocess::open_or_create, "myLock" );
}
因此现在到了调用关键代码部分的时候:
int MyClass::MyFunction()
{
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(
m_Lock, boost::interprocess::try_to_lock);
if(!lock)
{
return -1;
}
// else do some stuff here
}
为了在函数之后进行清理(就像 boost 页面上所描述的那样),我在类中使用了删除命令析构函数:
MyClass::~MyClass()
{
boost::interprocess::named_mutex::remove("myLock");
}
实际上所有这些代码都工作正常,但我有一个担忧:
正如删除命令的描述中所述:
从系统中删除指定的互斥体。出错时返回 false。从不抛出。
因此,这意味着删除命令只是将互斥锁从系统中删除 - 即使另一个线程刚刚锁定了它(我已经尝试过这种情况 - 它不再被锁定)。 所以我的问题如下: 例如,我有 3 个线程( A、B 和 C ) - 现在会发生以下情况:
- 进程 A 创建类的实例,调用函数并锁定它
- 进程 B 创建类的实例,调用函数但不能访问代码(然后等待,例如)
- 进程 A 完成受保护的代码并解锁
- 进程 B 获得对受保护代码的访问权限并锁定它
- 进程 A 删除该类的实例 ->删除命令被调用
- 进程 C 创建类的实例,调用函数并可以访问代码,因为删除命令删除了互斥体 -->错误!
所以现在有人可能会说“那就不要调用删除!” - 那么这可能吗?我的意思是,由于named_mutex写入系统,我怀疑即使程序结束,它也会在没有显式调用的情况下被删除。 有人有帮助吗?
I have a class which can be created by multiple threads. But at one function the code needs to be protected, so I decided to use the boost interprocess mutex. Every class creates or opens the same Mutex in it's constructor:
MyClass::MyClass()
{
boost::interprocess::named_mutex m_Lock(
boost::interprocess::open_or_create, "myLock" );
}
So now there comes the point where the critical code part is called:
int MyClass::MyFunction()
{
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(
m_Lock, boost::interprocess::try_to_lock);
if(!lock)
{
return -1;
}
// else do some stuff here
}
To clean up after the function ( and like its described on the boost page ) I use the remove command in my class destructor:
MyClass::~MyClass()
{
boost::interprocess::named_mutex::remove("myLock");
}
Actually all this code works fine, but there is one concern I have:
As it is said in the description of the remove command :
Erases a named mutex from the system. Returns false on error. Never throws.
So that means the remove command just erases the Mutex out of the system - even if another thread has just locked it ( I tried this case already - it isn't locked then anymore ).
So my problem is the following:
For example I have 3 Threads ( A, B and C ) - now the following happens:
- Process A creates an Instance of the class, calls the function and locks it
- Process B creates an Instances of the class, calls the function but can't access code ( then waits e.g. )
- Process A finishes with the protected code and it gets unlocked
- Process B gains access to the protected code and locks it
- Process A deletes the Instance of the class -> the remove command is called
- Process C creates an Instance of the class, calls the function and can access the code since the remove command erased the Mutex --> Error!
So now someone may say " Then don't call remove! " - Well is that possible? I mean since the named_mutex writes to the system I doubt it is erased without an explicit call, even if the program ends.
Anyone has some help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自 boost 文档,< code>remove 调用,是不必要的。
named_mutex
的析构函数会自动向操作系统表明该进程不再需要该资源。您可能只需要依靠析构函数的内置行为进行清理就可以了。如果显式调用remove,则可能会导致尝试使用指定互斥体的任何其他进程或线程对该互斥体的任何操作失败。根据您的使用安排方式,这可能会导致数据争用或在其他进程中引发崩溃/异常。
From the boost docs, the
remove
call, is unnecessary. The destructor ofnamed_mutex
will automatically take care indicating to the OS that the process no longer needs the resource. You're probably fine with just relying upon the built-in behavior of the destructor for cleanup.If you explicitly call remove, you'll likely cause any other processes or threads attempting to use the named mutex to fail on any operations on the mutex. Depending on how your usage is orchestrated, this could either cause data races or crashing/exceptions being thrown in other processes.
您可能需要一个互斥锁的共享使用计数器。在析构函数中锁定互斥体,将其递减,如果递减后它为零,则释放仍然锁定的互斥体。这样你就可以防止你当前的竞争状况。
You probably need a shared usage counter for the mutex. Lock the mutex in the destructor, decrement it, and if it's zero after the decrement, deallocate the still locked mutex. You will prevent your current race condition by that.
根据 boost 手册:
我想上面的内容应该已经解答了你的疑问。
According to the boost manual:
I think the above should have addressed your questions.