0

there are two solutions:

A:

lock()
try{
    action()
}catch(...)
{
    unlock()
    throw;
}
unlock()

B:

{
LockObject lockObject;
action();
}

LockObject's constuctor will call lock(),its de-construtor will call unlock().

So what's the better solution or is there any other better solution?

ps: in linux c++, it doesn't support keywords finally. So I have to make decision for this issue.

jiafu
  • 6,338
  • 12
  • 49
  • 73
  • Why don't you call `~Lock()` instead of `UnLock()`? – A B Feb 14 '14 at 06:01
  • Which looks better to you? – Martin York Feb 14 '14 at 06:05
  • both looks good, but it must has better one so I asked this issue. – jiafu Feb 14 '14 at 06:07
  • If I will be a programmer of this code I will use case A with all exception handling which will save my code form undefined behavior. – A B Feb 14 '14 at 06:11
  • @AnkitB, but solution B sees can do unlock after } too – jiafu Feb 14 '14 at 06:12
  • @jiafu But if any exception came in `action()` your code will show an `runtime` error as a programmer we have to keep in mind that it should not came. – A B Feb 14 '14 at 06:15
  • @AnkitB,but it still can unlock due to deconstruter be called? – jiafu Feb 14 '14 at 06:17
  • @jiafu I don`t think so. Because if any exception thrown by program/Application at `runtime` the memory which is allocated becomes garbage. – A B Feb 14 '14 at 06:20
  • 3
    @AnkitB, you're wrong; https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization and here's a SO q&a to help: http://stackoverflow.com/questions/161177/does-c-support-finally-blocks-and-whats-this-raii-i-keep-hearing-about – txtechhelp Feb 14 '14 at 06:24
  • @jiafu Thanks for such a nice documentation it helps me to furnish my knowledge. – A B Feb 14 '14 at 06:36
  • @jiafu, how are your `lock()/unlock()` methods implemented? In other words, do you have a `pthread_mutex_t` that sits as some static variable in a file/class/struct that you then lock? If this is the case, your `LockObject` might not function the way you're thinking?? – txtechhelp Feb 14 '14 at 06:41

1 Answers1

2

B is a special programming idiom called Resource Acquisition Is Initialization (RAII), and it can be applied in several programming languages such as C++, D, Ada.

When you want to acquire resource, you use initialization. And you release resource in destructor.

It is a well known idiom and it's also a good design in C++. In fact, C++ standard library uses it quite often.

For example,

// global mutex
std::mutex mutex;

void f()
{

    // lock mutex
    std::lock_guard<std::mutex> lock(mutex);

    //do something might throw exception
    //...

    //do not unlock mutex, it will be unlocked by lock_guard destructor  
}
user534498
  • 3,926
  • 5
  • 27
  • 52
  • can you give the full definition for the std::lock_guard? I will accept this answer. Many thanks to you. – jiafu Feb 14 '14 at 08:15
  • is stl::lock_guard contained in stl library? – jiafu Feb 14 '14 at 08:17
  • Hi jiafu, lock_guard is in c++11. If you don't have a c++11 compiler, you can use boost library. They are almost identical. A web reference of lock guard is http://en.cppreference.com/w/cpp/thread/lock_guard – user534498 Feb 14 '14 at 08:48
  • 1
    The design of lock_guard is quite straight-forward. Basically, lock_guard requires the resource it can lock to have two methods, lock() and unlock(), once your resource class has these two methods, it can be used with lock_guard. lock_guard will call lock() in constructor and call unlock() in destructor. – user534498 Feb 14 '14 at 08:51