在函数退出之前调用函数 [英] Call a function before function exits

查看:105
本文介绍了在函数退出之前调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将从一个例子开始.假设我需要使用互斥锁内的函数来保护代码.有两种实现方法.

I will begin with an example. Suppose I need to guard a code with a function inside a mutex. There are two ways of implementing this.

#include <iostream>
#include <vector>
#include <pthread.h>



pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
std::vector<float> myVec;

void threadfunc(int i, float value)
{
  pthread_mutex_lock(&myMutex);
  if(i <= 0 || i > myVec.size())
  {
    pthread_mutex_unlock(&myMutex);
    return;
  }

  if(value < 0)
  {
    pthread_mutex_unlock(&myMutex);
    return;
  }

  myVec[i] += value;
  pthread_mutex_unlock(&myMutex);
  return;
}

class AUTOMUTEX
{
  private:
    pthread_mutex_t *mMutex;
  public:
    AUTOMUTEX(pthread_mutex_t *mutex): mMutex(mutex)
  {
    pthread_mutex_lock(mMutex);
  }

    ~AUTOMUTEX()
    {
      pthread_mutex_unlock(mMutex);
    }
};


void threadfunc_autolock(int i, float value)
{
  AUTOMUTEX  autoMutex(&myMutex);
  if(i <= 0 || i > myVec.size())
  {
    return;
  }

  if(value < 0)
  {
    return;
  }

  myVec[i] += value;
  return;
}

int  main()
{
  threadfunc_autolock(5, 10);
  threadfunc(0, 7);
  return 1;
}

从示例中可以清楚地看出,threadfunc自动锁定是更好的实现,因为调用pthread_mutex_unlock函数的返回是通过对AUTOMUTEX的析构函数调用来解决的(C ++ 11线程对此提供了支持.因此,如果我们不需要自己的AUTOMUTEX实现,正在使用C ++ 11线程库). 有没有一种方法,我们每次需要通过一些set/reset函数对来实现而无需实现包装器类,就可以实现这一目标. boost或C ++ 11是否具有一些预定义的模板类,对于任何此类设置/重置"功能,我们都可以使用该模板类实现AUTOMUTEX的行为.这对于具有多个返回点的函数确实很有帮助. 换句话说,boost/C ++是否提供具有以下行为的类.

As it is clear from the example threadfunc autolock is better implementation as calling pthread_mutex_unlock function return is taken care by destructor call to AUTOMUTEX (C++ 11 thread has support for this. So we don't need our own implementation of AUTOMUTEX if we are using C++11 thread library). Is there a way we can achieve this without implementing a wrapper class each time we need to do this with some set/reset function pair. Does boost or C++ 11 have some predefined template class with which we can achieve the behaviour of AUTOMUTEX for any such "set/reset" sort of function. This is really helpful for functions with multiple points of return. In other words does boost/C++ provide a class with the following behaviour.

//sample code not compilable.
template <class T, class Y>
class myAuto
{
  myAuto()
{ 
   T();
}
  ~myAuto()
{
  Y();
};

推荐答案

您可以编写自己的通用RAII类,例如:

You may write your own geneirc RAII class, something like:

class Finally
{
public:
    explicit Finally(std::function<void()> f) : mF(f) {}
    ~Finally() noexcept() {
        try
        {
            mF();
        } catch (...) {
            // Handle error.
        } 
    }

    Finally(const Finally&) = delete;
    Finally(Finally&&) = delete;

    Finally& operator=(const Finally&) = delete;
    Finally& operator=(Finally&&) = delete;

private:
    std::function<void()> mF;
};

用法:

{
    pthread_mutex_lock(&myMutex);
    Finally finally([&](){ pthread_mutex_unlock(&myMutex); });

    //..
}

即使在某些情况下(例如Mutex),专用的RAII对象可能更合适.

Even if a dedicated RAII object may be more appropriate in some case (as Mutex).

这篇关于在函数退出之前调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆