除了事实,即在std::mutex
做了你并不需要在特定情况下,从构造函数抛出因为pthread_mutex_lock
actually returns an EINVAL if your mutex has not been initialized,您可以在通话后扔至lock
:
void
lock()
{
int __e = __gthread_mutex_lock(&_M_mutex);
// EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
if (__e)
__throw_system_error(__e);
}
然后在一般从施工人员投掷OK为收购在施工过程中的错误,并符合RAII(资源获取 - 初始化)编程范例。
入住这example on RAII
void write_to_file (const std::string & message) {
// mutex to protect file access (shared across threads)
static std::mutex mutex;
// lock mutex before accessing file
std::lock_guard<std::mutex> lock(mutex);
// try to open file
std::ofstream file("example.txt");
if (!file.is_open())
throw std::runtime_error("unable to open file");
// write message to file
file << message << std::endl;
// file will be closed 1st when leaving scope (regardless of exception)
// mutex will be unlocked 2nd (from lock destructor) when leaving
// scope (regardless of exception)
}
关注这些语句:
static std::mutex mutex
std::lock_guard<std::mutex> lock(mutex);
std::ofstream file("example.txt");
第一个声明是RAII和noexcept
。在(2)很明显,RAII施加在lock_guard
,它实际上可以throw
,而在(3)ofstream
似乎不是RAII,因为状态具有的对象通过调用is_open()
它检查failbit
标志进行检查。
乍看之下,似乎是在它的标准方式在第一种情况下std::mutex
不初始化扔拿不定主意,*对比OP实现*。在第二种情况下,它会抛出从std::mutex::lock
抛出的任何东西,而在第三种情况下根本没有抛出。
注意区别:
(1)可以声明静态的,实际上将被宣布为一个成员变量 (2)永远不会真正有望被声明为成员变量 (3)预计将被声明为成员变量,并且底层资源可能并不总是可用的。
所有这些形式都是RAII;要解决这个问题,必须分析RAII。
- 资源:你的对象
- 采集(分配):你对象被创建
- 初始化:你的目标是在其不变的状态
这并不是要求你初始化和连接一切建设。例如,当您创建一个网络客户端对象时,创建时实际上不会将其连接到服务器,因为这是一个运行缓慢的故障。你会写一个connect
函数来做到这一点。另一方面,您可以创建缓冲区或仅设置其状态。
因此,您的问题归结为定义您的初始状态。如果你的情况你的初始状态是互斥量必须初始化那么你应该从构造函数中抛出。相反,它只是没有初始化然后(如在std::mutex
中所做的那样),并将您的不变状态定义为互斥体创建为。在任何速率不变不受其成员对象的状态不一定compromized,由于通过Mutex
公共方法Mutex::lock()
和Mutex::unlock()
locked
和unlocked
之间的mutex_
对象发生突变。
class Mutex {
private:
int e;
pthread_mutex_t mutex_;
public:
Mutex(): e(0) {
e = pthread_mutex_init(&mutex_);
}
void lock() {
e = pthread_mutex_lock(&mutex_);
if(e == EINVAL)
{
throw MutexInitException();
}
else (e) {
throw MutexLockException();
}
}
// ... the rest of your class
};
关于相关主题的另一个链接:http://www.writeulearn.com/exception-constructor/ – 2014-11-04 17:38:41
可以从ctors扔掉尽可能多的东西,就像从其他函数中扔出来一样,被说你应该小心地扔掉来自任何功能。 – g24l 2015-12-26 23:04:52
不相干的东西:为什么不移除你的锁/解锁方法,直接在构造函数中锁定互斥锁,并在析构函数中解锁?这种方式只需在作用域中声明自动变量即可自动锁定/解锁,无需处理异常,返回等等。有关类似的实现,请参阅std :: lock_guard。 – 2016-07-07 08:25:44