Во-первых, все, что G_LOCK_DEFINE
делает, создает переменную GMutex
, имя которой кодирует имя переменной, защищающей ее, например. G_LOCK_DEFINE(mSomeCounter)
будет GMutex g__mSomeCounter_lock;
. Таким образом, мы можем расширить свой код, чтобы что-то вроде:
class CSomeClass {
private:
gulong mSomeCounter;
GMutex g__mSomeCounter_lock;
public:
CSomeClass();
};
CSomeClass::CSomeClass()
{
g_mutex_lock(&g__mSomeCounter_lock);
mSomeCounter = 0;
g_mutex_unlock(&g__mSomeCounter_lock);
}
Основная проблема здесь состоит в том, что вы не инициализируется любой членов класса CSomeClass
. Вы назначаете значения из них из них в конструкторе, но вы определенно не инициализируете их. Там разница между заданием в фигурных скобках, и используя инициализатор, такие как:
CSomeClass::CSomeClass() : mSomeCounter(0)
В результате мьютекс, который создается, названный против переменного может содержать мусор. Вероятно, что-то в glib-коде, который бы изменился, чтобы это произошло, скорее всего, изменения в других библиотеках изменили расположение памяти вашего приложения, обнаружив ошибку.
В glib documentation намеки, что вам нужно g_mutex_init
мьютексами:
, которая была выделена в стеке, или как часть более крупной структуры
Вам не нужно g_mutex_init
мьютексы, что :
Нет необходимости инициализировать мьютексы, статически распределенные
Классные экземпляры почти всегда не статически выделенные.
Вам необходимо исправить ваш конструктор, чтобы убедиться, что он инициализирует мьютекс «правильно», например.:
CSomeClass::CSomeClass()
{
g_mutex_init(&G_LOCK_NAME(mSomeCounter));
G_LOCK(mSomeCounter);
mSomeCounter = 0;
G_UNLOCK(mSomeCounter);
}
ТВН, я бы поставил семафор в держатель класса, и инициализировать его как часть этого, а не так, как вы делаете это, чтобы убедиться, что он будет инициализирован, заблокирован и разблокирован, как часть стандартной семантики C++ RAII.
Если вы используете небольшой основной корешок, что-то вроде:
main() {
{ CSomeClass class1; }
{ CSomeClass class2; }
{ CSomeClass class3; }
}
и ваш код, есть хороший шанс, что он будет висеть в любом случае. (Мой макинтош разбился пример с:. GLib (gthread-posix.c): Unexpected error from C library during 'pthread_mutex_lock': Invalid argument. Aborting.
некоторые простые, например, Непроизводственные оберток, чтобы помочь с RAII:
class CGMutex {
GMutex mutex;
public:
CGMutex() {
g_mutex_init(&mutex);
}
~CGMutex() {
g_mutex_clear(&mutex);
}
GMutex *operator&() {
return &mutex;
}
};
class CGMutexLocker {
CGMutex &mRef;
public:
CGMutexLocker(CGMutex &mutex) : mRef(mutex) {
g_mutex_lock(&mRef);
}
~CGMutexLocker() {
g_mutex_unlock(&mRef);
}
};
class CSomeClass {
private:
gulong mSomeCounter;
CGMutex mSomeCounterLock;
public:
CSomeClass();
};
CSomeClass::CSomeClass()
{
CGMutexLocker locker(mSomeCounterLock); // lock the mutex using the locker
mSomeCounter = 0;
}
инициализации mSomeCounter гарантирует, что счетчик инициализируется, в противном случае она будет иметь мусор