Kai*_*aiJ 2 c mutex thread-safety
以C中的对象为例:
/* object.h */
typedef struct Object Object;
Object* createObject();
void freeObject(Object* object);
int getObjectNumber(Object* object);
void incrementObjectNumber(Object* object);
Run Code Online (Sandbox Code Playgroud)
这是一种非常简单的不透明类型,它存储一个数字并可以递增。
为了使我的代码线程安全,我有两个选择。第一种是在对象中存储互斥量:
void
func(Object* object)
{
incrementObject(object);
}
int
main()
{
Object* object = createObject();
Thread thread1 = startThread(func, object);
Thread thread2 = startThread(func, object);
waitThread(thread1);
waitThread(thread2);
freeObject(object);
}
Run Code Online (Sandbox Code Playgroud)
第二种是将互斥锁存储在main中:
void
func(Object* object, Mutex mutex)
{
lockMutex(mutex);
incrementObject(object);
unlockMutex(mutex);
}
int
main()
{
Object* object = createObject();
Mutex mutex;
Thread thread1 = startThread(func, object, mutex);
Thread thread2 = startThread(func, object, mutex);
waitThread(thread1);
waitThread(thread2);
freeObject(object);
}
Run Code Online (Sandbox Code Playgroud)
如果只会有一个对象,哪种方法更好?
无论有一个对象还是多个对象,将互斥体与不透明的对象一起存储都是一个好主意。首先,互斥锁及其保护的数据属于同一类。而且,线程安全需要由您的“ ADT”来处理,而不是由调用者来处理。对对象的访问应仅通过设置器/获取器进行,后者将在内部处理线程安全性。在这种情况下incrementObject。
这样,您可以声明您的整个库是线程安全的,它会照顾自己而不是将责任转嫁给其他人。您的第一个示例的API更加简洁,而第二个示例则要求调用者将一个互斥锁拖到其用户定义的回调中,这不是一个干净的解决方案。