noncopyable.h
#ifndef NONCOPYABLE_H
#define NONCOPYABLE_H
namespace muduo
{
class noncopyable
{
public:
noncopyable(const noncopyable&) = delete;
void operator=(const noncopyable&) = delete;
protected:
noncopyable() = default;
~noncopyable() = default;
};
} // namespace muduo
#endif
mutexLockGuard.h
#ifndef MUTEXLOCKGUARD_H
#define MUTEXLOCKGUARD_H
#include "noncopyable.h"
#include <pthread.h>
namespace muduo {
class MutexLock : public muduo::noncopyable //表达语义
{
public:
MutexLock() { pthread_mutex_init(&_mutex, NULL); }
~MutexLock() { pthread_mutex_destroy(&_mutex); }
void lock() { pthread_mutex_lock(&_mutex); }
void unlock() { pthread_mutex_unlock(&_mutex); }
pthread_mutex_t *getMutexLockPtr() { return &_mutex; }
private:
pthread_mutex_t _mutex;
};
// RAII
class MutexLockGuard {
public:
MutexLockGuard(MutexLock &mutex) : mutexLock_(mutex) { mutexLock_.lock(); }
~MutexLockGuard() { mutexLock_.unlock(); }
private:
MutexLock &mutexLock_;
};
} // namespace muduo
#endif
test.cc
#include "mutexLockGuard.h"
#include <iostream> // std::cout
#include <thread> // std::thread
#include <vector> // std::vector
using namespace muduo;
class Counter : muduo::noncopyable {
public:
Counter() : value_(0) {}
int value() const;
int getAndIncrease();
private:
int value_;
mutable MutexLock mutex_;
};
int Counter::value() const {
MutexLockGuard lock(mutex_);
return value_;
}
int Counter::getAndIncrease() {
MutexLockGuard lock(mutex_);
int ret = value_++;
return ret;
}
void increase_global(Counter &cnt, int n) {
for (int i = 0; i < n; ++i)
cnt.getAndIncrease();
}
int main() {
Counter cnt;
std::vector<std::thread> threads;
std::cout << "increase global counter with 10 threads...\n";
for (int i = 1; i <= 10; ++i)
threads.push_back(std::thread(increase_global, std::ref(cnt), 100));
std::cout << "synchronizing all threads...\n";
for (auto &th : threads)
th.join();
std::cout << "global_counter: " << cnt.value() << '\n';
return 0;
}