我试图摆脱代码中的一些boost依赖项,而是使用新的C++ 11特性(Visual Studio 2013).
在我的组件之一我曾经boost::mutex一起boost::lock_guard<boost::mutex>和一切工作正常.当我std::mutex一起使用时std::lock_guard<std::mutex>,我从返回时收到以下错误main().
GrabberTester.exe中0x7721E3BE(ntdll.dll)的未处理异常:0xC0000005:访问冲突读取位置0xA6A6B491.
真正的项目非常复杂,因此难以提供完整的工作代码示例来重现此问题.在我的真实项目中,互斥体用在一个在运行时加载的共享库中(但是在我返回时应该已经卸载了它main()).
我的问题是:
boost::mutex和std::mutex设计表现完全相同?std::mutex代替boost::mutex?boost::thread框架创建线程.可能std::mutex只能用于std::threads并且与boost::threads 不兼容吗?我注意到的另一件事是:当我卸载动态加载的共享库时,这需要一些时间.(DLL访问硬件,干净地关闭所有内容需要一些时间).当我切换到std::mutex它时,看起来几乎可以立即卸载DLL,但程序然后在返回时崩溃main().我的印象是问题std::mutex特别是在DLL的上下文中.
应用程序和DLL都是使用v120工具集在Debug配置中新建的,并与运行时库(/ MTd)静态链接.
下面你可以找到callstack.例外似乎来自驱动程序中的某个地方.只是偶然我发现它与我使用的互斥锁的实现有关.
ntdll.dll!7721e3be()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7721e023()
kernel32.dll!76b014ad()
msvcr100.dll!71b0016a()
PS1080.dll!oniDriverDestroy() Line 29
OpenNI2.dll!oni::implementation::DeviceDriver::~DeviceDriver() Line 95
OpenNI2.dll!oni::implementation::Context::shutdown() Line 324
OpenNi2Grabber.dll!openni::OpenNI::shutdown() Line …Run Code Online (Sandbox Code Playgroud) 我可以boost::lock_guard用来获取一个boost::mutex对象的锁,这个机制将确定一旦boost::lock_guard超出范围,锁将被释放:
{
boost::lock_guard<boost::mutex> lock(a_mutex);
// Do the work
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,a_mutex无论代码块是否被异常退出,都将被释放.
另一方面,a boost::timed_mutex还支持一种方法try_lock_for(period),例如
if(a_timed_mutex.try_lock_for(boost::chrono::seconds(1))) {
// Do the work
a_timed_mutex.unlock(); // <- This is needed!
} else {
// Handle the acquisition failure
}
Run Code Online (Sandbox Code Playgroud)
此代码将不会unlock()在a_timed_mutex如果true该块if声明退出与异常.
问题: Boost(以及据我所知,C++ 11标准)似乎没有提供lock_guard适用于try_lock()或的变体try_lock_for(period).处理第二种情况的"推荐"方式或最佳做法是什么?
我缩短的简化课程如下:
class A
{
public:
// ...
methodA();
methodB();
protected:
mutable boost::mutex m_mutex;
sometype* m_myVar;
}
A::methodA( int someParam )
{
boost::mutex::scoped_lock myLock(m_mutex);
m_myVar->doSomethingElse();
}
A::methodB( int someParam )
{
boost::mutex::scoped_lock myLock(m_mutex);
m_myVar->doSomething();
this->methodA(someParam);
}
Run Code Online (Sandbox Code Playgroud)
我想同步访问m_myVar.在调用时A::methodB(),线程会使用相同的互斥锁两次进入锁定状态,并且明显会阻塞第一行A::methodA()
有没有办法在再次传递时scoped_lock不阻止同一个线程?
当然,我只是可以打电话m_mutex.unlock().但这也会释放其他线程等待锁定 - 这绝对不是我想要的.
任何的想法?
最好的问候托比亚斯
堆栈溢出有几个例子,其中一个函数获得的升级锁第一和然后获得由升级的独占访问.我的理解是,如果不小心使用,这会导致死锁,因为两个线程都可以获得可升级/共享锁,然后两者都尝试升级,此时两者都不能继续,因为另一个具有共享锁.
我想要的是首先获得独占锁,然后降级到共享锁,而不完全释放锁.我找不到这样的例子.有任何想法吗?
我有一个c ++类,分配了大量的内存.它通过调用第三方库来实现这一点,如果它无法分配内存,则会崩溃,有时我的应用程序会在并行线程中创建我的类的多个实例.由于线程太多,我遇到了崩溃.我最好的解决方案是确保从不会有超过三个实例同时运行.(这是一个好主意吗?)和我为实现当前最好的办法即是使用升压互斥.以下伪代码的行,
MyClass::MyClass(){
my_thread_number = -1; //this is a class variable
while (my_thread_number == -1)
for (int i=0; i < MAX_PROCESSES; i++)
if(try_lock a mutex named i){
my_thread_number = i;
break;
}
//Now I know that my thread has mutex number i and it is allowed to run
}
MyClass::~MyClass(){
release mutex named my_thread_number
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我不太确定互斥体的确切语法.所以总结一下,我的问题是
编辑:我意识到我在谈论线程,而不是进程.编辑:我参与构建可以在Linux和Windows上运行的应用程序...
我想在其他地图中锁定键/索引,如下所示:
std::map<int, boost::mutex> pointCloudsMutexes_;
pointCloudsMutexes_[index].lock();
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误:
/usr/include/c++/4.8/bits/stl_pair.h:113: error: no matching function for call to 'boost::mutex::mutex(const boost::mutex&)'
: first(__a), second(__b) { }
^
Run Code Online (Sandbox Code Playgroud)
它似乎可以使用std::vector,但不是std::map.我究竟做错了什么?
我想知道如果我同时持有两个boost :: scoped_locks会有任何问题.锁定锁定不同的互斥锁.请考虑以下示例:
void foo1()
{
boost::recursive_mutex::scoped_lock lock(mutex1);
foo2();
}
void foo2()
{
boost::recursive_mutex::scoped_lock lock(mutex2);
}
Run Code Online (Sandbox Code Playgroud)
我知道这不会导致僵局.但是还有其他问题吗?也许这会导致线程睡眠时间过长?
我对 boost 很陌生,只是想了解其中的一小部分 - 进程间互斥体。
AFAIU,使用文件锁的跨平台实现中有一个强大的互斥模拟:http://www.boost.org/doc/libs/1_62_0/boost/interprocess/detail/robust_emulation.hpp
这是为了模拟 posix 标准中可用的强大互斥锁,但只有当平台特定版本不可用时才会使用通用方法。
#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
#include <boost/interprocess/sync/posix/mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
#include <boost/interprocess/sync/windows/mutex.hpp>
#define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Run Code Online (Sandbox Code Playgroud)
但是在实际上支持健壮互斥体的posix系统上(我猜这取决于内核版本),健壮互斥体实际上没有启用。http://www.boost.org/doc/libs/1_62_0/boost/interprocess/sync/posix/pthread_helpers.hpp
所以我不太明白这里的逻辑,posix 强大的互斥体实现是否有严重的性能损失,以至于我们不想使用它?即便如此,至少应该有一个选项可以选择性地启用此功能。
为了解决这个问题,因为我是新手,有什么方法可以使通用实现在 posix 实现上可用,以便我可以利用鲁棒性?
为了学习boost :: thread的组合,我正在为线程实现一个简单的屏障(BR)来锁定一个普通的互斥锁(M).但是,就我转到BR.wait()而言,互斥锁上的锁定没有释放,因此为了让所有线程都到达BR,需要手动释放M上的锁定.所以我有以下代码:
boost::barrier BR(3);
boost::mutex M;
void THfoo(int m){
cout<<"TH"<<m<<" started and attempts locking M\n";
boost::lock_guard<boost::mutex> ownlock(M);
cout<<"TH"<<m<<" locked mutex\n";
Wait_(15); //simple wait for few milliseconds
M.unlock(); //probably bad idea
//boost::lock_guard<boost::mutex> ~ownlock(M);
// this TH needs to unlock the mutex before going to barrier BR
cout<<"TH"<<m<<" unlocked mutex\n";
cout<<"TH"<<m<<" going to BR\n";
BR.wait();
cout<<"TH"<<m<<" let loose from BR\n";
}
int main()
{
boost::thread TH1(THfoo,1);
boost::thread TH2(THfoo,2);
boost::thread TH3(THfoo,3);
TH2.join(); //but TH2 might end before TH1, and so destroy BR …Run Code Online (Sandbox Code Playgroud) 目前在我的代码中我有这样的部分
boost::mutex Mymutex
void methodA()
{
boost::mutex::scoped_lock lock(Mymutex);
......
......
......
}
Run Code Online (Sandbox Code Playgroud)
我读到关键部分比互斥锁更快?所以我正在做这样的事情,我想知道这是否更快.
boost::recursive_mutex m_guard;
void methodA()
{
// this section is not locked
{
boost::lock_guard<boost::recursive_mutex> lock(m_guard);
// this section is locked
}
//This section not locked
}
Run Code Online (Sandbox Code Playgroud)
第二种方法更快吗?我主要使用互斥锁的原因是为了防止竞争条件和锁定对方法的访问,以便一个线程一次访问它.还有什么比这更快的吗?我的另一个问题是声明
boost::lock_guard<boost::recursive_mutex> lock(m_guard);
Run Code Online (Sandbox Code Playgroud)
似乎每次调用methodA()都会在堆栈上创建锁.我正在考虑将lock声明为静态变量,因此每次调用此方法时都不会在堆栈上创建它.在这种情况下,如何将m_guard添加到它.例如
boost::recursive_mutex SomeClass::m_guard; //This is static
boost::lock_guard<boost::recursive_mutex> SomeClass::lock //Suppose this is static
void SomeClass::methodA()
{
{
//How do i make lock "lock" mguard
}
}
Run Code Online (Sandbox Code Playgroud) boost-mutex ×10
c++ ×9
boost ×4
mutex ×3
boost-thread ×2
c++11 ×1
openni ×1
scoped-lock ×1
stdmap ×1