我正在尝试基于Allegro互斥锁(跨平台)创建自定义互斥锁类。我不使用C ++ 11。我试图这样做,但似乎有点多余:
template <class T>
class Mutex
{
private:
ALLEGRO_MUTEX *mutex = NULL;
ALLEGRO_THREAD *owner = NULL;
T *data = NULL;
public:
Mutex ();
Mutex (T* data);
~Mutex ();
bool lock (ALLEGRO_THREAD* thread);
bool unlock (ALLEGRO_THREAD* thread);
bool trylock (); //Returns true if you can lock the thread
bool set (T* data, ALLEGRO_THREAD* thread);
bool get (T** data, ALLEGRO_THREAD* thread); //Pass reference of pointer
}
构造函数将调用al_create_mutex()
,如果是第二个,则设置数据指针。析构函数调用al_destroy_mutex()
。
lock方法将检查owner
是否为NULL
(表示互斥锁已解锁且没有线程拥有它)。如果是NULL
,则会设置owner = thread
并锁定互斥锁。解锁方法会在thread == owner
解锁互斥锁并设置owner = NULL
。
trylock方法只是检查是否owner == NULL
,表明互斥锁未被任何线程锁定。
只有当调用线程是锁定的互斥锁的所有者时,set
和get
方法才会设置并返回存储的指针。
我有一种感觉,每次你想调用一个方法时,我都会有点过分通过线程,但我没有看到任何其他方法使这个类线程安全,因为Allegro没有没有al_get_current_thread()
函数或类似的东西。我该怎么办这个班?
答案 0 :(得分:1)
我强烈建议您创建一个仅包含Allegro互斥锁功能的类,而不执行任何其他操作。然后创建一个单独的模板类,它使用互斥锁提供对数据的独占访问。
您对Mutex::owner
的访问需要同步以避免数据争用。如果您确实想要提供递归和/或trylock行为,请在单独的类或类中执行此操作,这些类或类在其实现中使用基本互斥锁。 (提示:使用一个互斥锁来保护owner
字段,使用另一个互斥锁为客户提供实际的互斥。)
我怀疑没有ALLEGRO_THREAD
参数的基本RAII包装器是你真正需要的。