无法锁定Qt互斥锁(QReadWriteLock)访问冲突写入

时间:2012-11-13 13:41:31

标签: c++ multithreading qt mutex

这个问题的一些背景是我之前的问题: non-member function pointer as a callback in API to member function(可能无关紧要)。

回调启动一个写入一些数据的线程。还有另一个线程读取相同的数据,导致一些崩溃。 我刚刚参加了多线程的速成课程(感谢SO),这是我试图保证作者和读者不能同时访问数据。我正在使用Qt(QReadWriteLock)的一些互斥机制。

#include <QSharedPointer>
#include <QReadWriteLock>

Class MyClass
{
public:
  MyClass();
  bool open();
  float getData();
  void streamCB(void* userdata);

protected:
  float private_data_;
  QSharedPointer<QReadWriteLock> lock_;
};

// callback wrapper from non-member C API to member function void
__stdcall streamCBWrapper(void* userdata)
{
   static_cast<MyClass*>(userdata)->streamCB(userdata);
}

// constructor
MyClass::MyClass()
{
  lock_ = QSharedPointer<QReadWriteLock>(new QReadWriteLock());
  lock_->lockForWrite();
  private_data_ = getData();
  lock_->unlock();
}

// member callback
void MyClass:streamCB(void* userdata)
{
  float a = getData(); 
  lock_->lockForWrite(); //*** fails here
  private_data_ = a;
  lock_->unlock();
}

运行程序时出现分段错误。 VS调试器在我标记为Access violation writing location 0x00fedbed.的行上显示//*** fails here. 锁在构造函数中工作,但不在回调中。

知道出了什么问题吗?我该怎么看? (以及如何改进我的问题) 谢谢!

其他相关主题 Cannot access private member declared in class 'QReadWriteLock'Error 1 error C2248: 'QReadWriteLock::QReadWriteLock'(我使用了QSharedPointer建议)

编辑1: 回调已设置

bool MyClass::open()
{
  // stuffs
  int mid = 0;
  set_stream_callback(&streamCBWrapper, &mid);
  // more stuffs
  return true;
}

编辑2: 谢谢你提出的所有建议。 所以我的错误可能根本不是因为互斥锁,而是因为我对API缺乏了解?我很困惑..这是set_stream_callback的API文档。

typedef void (__stdcall *STREAM_CALLBACK)(void *userdata);

/*! @brief Register a callback to be invoked when all subscribed fields have been updated
 *
 *  @param streamCB pointer to callback function
 *  @param userdata pointer to private data to be passed back as argument to callback
 *  @return 0 if successful, error code otherwise
 */
__declspec(dllimport) int __stdcall set_stream_callback(
    STREAM_CALLBACK streamCB, void *userdata);

2 个答案:

答案 0 :(得分:1)

为什么需要足够的代码示例的好例子。

如果我正确解释你的回调语法,

set_stream_callback(&amp; streamCBWrapper,&amp; mid);

streamCBWrapper设置为回调函数,而&mid是指向userdata的指针。

在回调中,您实际上是int投射指向MyClass 的指针,然后尝试访问不存在的对象的成员变量。

确保将MyClass的实例传递给您的回调。我认为在你的情况下这将是this

答案 1 :(得分:0)

对我而言,根本就像是一个线程问题。既然你还在使用Qt静音,你可以考虑使用Qt的线程机制并在线程之间发送信号和插槽。只要您遵循herehere建议,它们就会有很好的文档记录并且易于使用。