Effective C++ Item 14-在资源管理中小心的copying行为
程序员文章站
2023-04-02 15:20:49
Item 14-在资源管理中小心的copying行为(Think carefully about copying behavior in resource-managing cla...
Item 14-在资源管理中小心的copying行为(Think carefully about copying behavior in resource-managing classes)
auto_ptr和trl::shared_ptr表现在heap_based资源上,然而并非所有资源都是heap_based,这样我们就需要建立自己的资源管理类。
例如:假设我们使用C API(Application Programming Interface)函数处理类型为Mutex的互斥器对象(mutex objects),共有lock和unlock两函数可用:
void lock(Mutex* pm); //锁定pm所指的互斥器 void unlock(Mutex* pm); //将互斥器解除锁定
Note:Mutex是Windows中用于对线程控制的互斥量。意思是只能有一个线程取得对它的占有权,因为有些业务只允许一个线程进行控制。打个比方:一个房间每次只允许一个人进去,而当有多个人需要使用那个房间时,就需要进行控制,其他人必须排队,这个控制就需要设置一个互斥量。
为确保绝不忘记将一个被锁住的Mutex解锁,你可能会希望建立一个class用来管理机锁。这样的class的基本结构由RAII守则支配,也就是"资源在构造期间获得,在析构期间释放"。
class Lock { public: explicit Lock(Mutex* pm):mutexPtr(pm){Lock(mutexPtr);} //获得资源 ~Lock(){unlock(mutexPtr);} //释放资源 private: Mutex* mutexPtr; };客户对Lock的用法符合RAII方式:
Mutex m; //定义你需要的互斥器 ... { //建立一个区块用来定义critical section Lock ml(&m); //锁定互斥器 ... //执行critical section内的操作 } //在区块最末尾,自动解除互斥器锁定Note:critical section临界区。不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问。每个线程中访问临界资源的那段代码成为临界区。
如果Lock对象被复制;
Lock ml1(&m) //锁定m Lock ml2(ml1) //将ml1复制到ml2身上。?怎么办
四种选择;
1、禁止复制
2、将底层资源使用"引用计数法"(reference-count)
3、复制底部资源
4、转移底部资源的拥有权
请记住:
复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
普遍而常见的RAII class copying行为是:抑制copying、使用引用计数法(reference counting)。不过其他行为也都可能被实现。