boost :: mutex, вызываемый другим проектом, дает нарушение прав доступа - PullRequest
0 голосов
/ 24 мая 2018

Я работаю над решением, включающим 2 проекта: .DLL, созданный с помощью набора инструментов v80 (C ++ 98), и .EXE с использованием набора инструментов v110 (ранее C ++ 11).Причина в том, что решение постепенно мигрирует на C ++ 11, а версия vDL .DLL все еще имеет зависимости, препятствующие обновлению.В конце концов, это будет исправлено ...

.DLL v80 прослушивает сеть, ставит в очередь события (которые впоследствии будут перевариваться с помощью v110 .EXE) и контролирует доступ к очереди с помощью boost :: mutex,В обоих проектах используется одна и та же версия ресурсов повышения (1.58.8.6 для ms80).

Когда класс EventListener v80 блокирует мьютекс, проблемы, похоже, нет.Чтобы проверить это, я вызывал методы-члены, используя мьютекс из конструктора EventListener.Блокировки в области видимости и вызовы lock () / unlock () работают нормально.

ПРОБЛЕМА:

Когда диспетчер v110 вызывает методы EventListener (такие классы, как clearQueue ()или ~ EventListener () блокирует мьютекс) Я получаю ошибку нарушения доступа при попытке заблокировать мьютекс.В этой строке выдается ошибка:

// in boost\thread\win32\thread_primitive.hpp
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
    return _interlockedbittestandset(x,bit)!=0;  <-- 0xC0000005: Access violation writing location 0x00EC1644
}

Некоторые дополнительные сведения:

  • член класса мьютекса boost::mutex* инициализируется с помощью new boost::mutex() при инициализации конструктора
  • когда мьютекс заблокирован, это с boost::mutex::scoped_lock lock(*mQueueMutex);

Я думаю, что, возможно, когда вызов сделан v110 .EXE, контекст / разрешение для _interlockedbittestandsetвызов по-другому отличается и может привести к ошибке ... но пока я ничего не могу подкрепить этой теорией.

РЕДАКТИРОВАТЬ

Придумала минимальный, полный и проверяемый пример самостоятельно, но я не смог воссоздать проблему .Я должен сказать, что это было отличное упражнение на рефлексию, чтобы сделать пример и попытаться сузить проблему, это было также быстрее, чем я думал!

Я настоятельно рекомендую всем попробовать это перед публикацией здесь, и предложить скромныйизвинения всем, кто посчитал меня спамом.

А пока я попытаюсь выяснить, в чем действительно проблема.

v110 code

#include <iostream>
#include <thread>
#include "../BoostMutexTest/MutexOwningClass_v80.h"

void work(MutexOwningClass_v80* m)
{
  m->lockMutex();
}

void main()
{
  MutexOwningClass_v80* v80_Class = new MutexOwningClass_v80();

  std::thread t1(&work,v80_Class);
  std::thread t2(&work,v80_Class);
  std::thread t3(&work,v80_Class);
  std::thread t4(&work,v80_Class);

  t1.join();
  t2.join();
  t3.join();
  t4.join();
}

v80 code

#include "boost/thread.hpp"

struct MutexOwningClass_v80
{
  MutexOwningClass_v80();
  void lockMutex();
private:
  boost::mutex* m;
};

#include "MutexOwningClass_v80.h"
#include <iostream>

MutexOwningClass_v80::MutexOwningClass_v80(): m(new boost::mutex())
{}

void MutexOwningClass_v80::lockMutex()
{
  boost::mutex::scoped_lock lock(*m);
  std::cout << "My mutex is locked!" << std::endl; 
}

вывод (неудивительно ...)

My mutex is locked!
My mutex is locked!
My mutex is locked!
My mutex is locked!
...