C++11 实现defer

defer函数功能还是蛮常用的,它是在出当前作用域的时候执行,用来回收资源非常合适,可惜C++里面没有,以前实现起来都比较别扭现在用C++11实现后看起来简单多了。

此defer内部lambda表达式捕获的是引用;

同一个作用域内先定义的defer后执行;

使用define以及x##y连接符的作用是,每次定义的局部变量名都是唯一的,使用起来非常方便,否则你可能需要像下面这种写法,每次还要考虑局部变量名不能重名,可能是如下写法:

    auto _defer_ = defer_func([] {
        std::cout << "defer" << std::endl;
    });

定义宏之后用起来就简洁多了:

defer( std::cout << "defer" << std::endl );

源码如下:

#pragma once

template <typename F>
struct privDefer {
    F f;
    privDefer(F f) : f(f) {}
    ~privDefer() { f(); }
};

template <typename F>
privDefer<F> defer_func(F f) {
    return privDefer<F>(f);
}

#define DEFER_1(x, y) x##y
#define DEFER_2(x, y) DEFER_1(x, y)
#define DEFER_3(x)    DEFER_2(x, __COUNTER__)
#define defer(code)   auto DEFER_3(_defer_) = defer_func([&](){code;})

用法如下:

void foo1() {
    defer(std::cout << "foo1 end" << std::endl);
    std::cout << "foo1 start" << std::endl;
}

void foo2() {
    std::cout << "foo2 start" << std::endl;
    defer(std::cout << "fist defer" << std::endl);
    std::cout << "foo2 handle" << std::endl;
    defer(std::cout << "second defer" << std::endl);
    defer(std::cout << "third defer" << std::endl);
    std::cout << "foo2 end" << std::endl;
}

void foo3() {
    int i = 0;
    defer(std::cout << "foo3 i:" << i << std::endl;);
    for (; i < 5; i++) {
        std::cout << i << std::endl;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哲学家进餐问题是一个经典的并发问题,涉及多个哲学家在桌子上围坐并尝试拿起左右两侧的筷子进餐,但是只有当左右两侧的筷子都可用时,才能够进餐。如果所有哲学家都试图同时进餐,就会出现死锁的情况,因为每个哲学家都在等待其他人放下筷子。 以下是使用C++实现的一种解决方案,其中使用了互斥锁和条件变量来确保每个哲学家都能够进餐,而且不会出现死锁情况。 ```c++ #include <iostream> #include <thread> #include <mutex> #include <condition_variable> using namespace std; const int NUM_PHILOSOPHERS = 5; mutex forks[NUM_PHILOSOPHERS]; condition_variable cv[NUM_PHILOSOPHERS]; void philosopher(int id) { int left_fork = id; int right_fork = (id + 1) % NUM_PHILOSOPHERS; while (true) { // 拿起左边的叉子 unique_lock<mutex> left_lock(forks[left_fork]); // 尝试拿起右边的叉子 unique_lock<mutex> right_lock(forks[right_fork], defer_lock); // 如果右边的叉子被其他哲学家拿走了,就等待 while (!right_lock.try_lock()) { cv[left_fork].wait(left_lock); } // 吃饭 cout << "Philosopher " << id << " is eating." << endl; this_thread::sleep_for(chrono::seconds(1)); // 放下叉子 right_lock.unlock(); cv[(left_fork + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS].notify_one(); left_lock.unlock(); cv[left_fork].notify_one(); // 思考 cout << "Philosopher " << id << " is thinking." << endl; this_thread::sleep_for(chrono::seconds(1)); } } int main() { thread philosophers[NUM_PHILOSOPHERS]; for (int i = 0; i < NUM_PHILOSOPHERS; i++) { philosophers[i] = thread(philosopher, i); } for (int i = 0; i < NUM_PHILOSOPHERS; i++) { philosophers[i].join(); } return 0; } ``` 在这个例子中,每个哲学家都是一个独立的线程,它们尝试拿起左右两侧的筷子,如果两侧的筷子都可用,就进餐一段时间,然后放下筷子,进行思考。当某个哲学家拿起了左边的筷子,但是右边的筷子被其他哲学家拿走时,它就会等待右边的筷子被放下,并通过条件变量通知左边的哲学家可以重新尝试拿起左边的筷子。这样,每个哲学家都可以进餐,并且不会出现死锁情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值