版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zeqi1991/article/details/82526010
noncopyable.h
#ifndef __INCLUDE_NONCOPYABLE_H__
#define __INCLUDE_NONCOPYABLE_H__
class noncopyable
{
public:
noncopyable();
virtual ~noncopyable();
private:
noncopyable(const noncopyable&);
noncopyable& operator=(const noncopyable&);
};
#endif//__INCLUDE_NONCOPYABLE_H__
noncopyable.cpp
#include "noncopyable.h"
noncopyable::noncopyable()
{
}
noncopyable::~noncopyable()
{
}
首先封装一个mutex_lock的类
mutex_lock.h
#ifndef __INCLUDE_MUTEX_LOCK_H__
#define __INCLUDE_MUTEX_LOCK_H__
#include "noncopyable.h"
#include <pthread.h>
#include <assert.h>
#include <sys/types.h>
class MutexLock : public noncopyable
{
public:
MutexLock();
~MutexLock();
public:
void Lock();
void Unlock();
pthread_mutex_t* GetMutexInstance();
bool IsLockByThisThread() const;
void AssertLocked() const;
//后面配合条件变量使用的
friend class Condition;
class UnassignGuard : public noncopyable
{
public:
UnassignGuard(MutexLock& owner) : owner_(owner)
{
owner_.UnAssignHolder();
}
~UnassignGuard()
{
owner_.AssignHolder();
}
private:
MutexLock& owner_;
};
private:
void AssignHolder();
void UnAssignHolder();
private:
pthread_mutex_t mutex_;
//所在线程的id
pid_t holder_;
};
#endif //__INCLUDE_MUTEX_LOCK_H__
mutex_lock.cpp
#include "mutex_lock.h"
#include <sys/syscall.h>
#include <unistd.h>
MutexLock::MutexLock()
{
pthread_mutex_init(&mutex_, NULL);
}
MutexLock::~MutexLock()
{
assert(holder_ == 0);
pthread_mutex_destroy(&mutex_);
}
void MutexLock::Lock()
{
pthread_mutex_lock(&mutex_);
AssignHolder();
}
void MutexLock::Unlock()
{
UnAssignHolder();
pthread_mutex_unlock(&mutex_);
}
pthread_mutex_t* MutexLock::GetMutexInstance()
{
return &mutex_;
}
bool MutexLock::IsLockByThisThread() const
{
return holder_ == (pid_t)(syscall(__NR_gettid));
}
void MutexLock::AssertLocked() const
{
assert(IsLockByThisThread());
}
void MutexLock::AssignHolder()
{
holder_ = (pid_t)(syscall(__NR_gettid));
}
void MutexLock::UnAssignHolder()
{
holder_ = 0;
}
测试文件main.cpp
#include <iostream>
#include "mutex_lock.h"
using namespace std;
int g_number = 0;
MutexLock lock;
void* Add(void* arg)
{
lock.Lock();
int &num = *((int*)(arg));
for (int i = 0; i < 10000; i++)
{
++num;
}
lock.Unlock();
return NULL;
}
void* Subtraction(void* arg)
{
lock.Lock();
int &num = *((int*)(arg));
for (int i = 0; i < 10000; i++)
{
--num;
}
lock.Unlock();
return NULL;
}
int main()
{
pthread_t thread_pid_t1, thread_pid_t2;
pthread_create(&thread_pid_t1, NULL, Add, &g_number);
pthread_create(&thread_pid_t2, NULL, Subtraction, &g_number);
pthread_join(thread_pid_t1, NULL);
pthread_join(thread_pid_t2, NULL);
std::cout << "g_number = " << g_number << std::endl;
return 0;
}
makefile
#sample makefile
CC := g++
DEFS := -D _DEBUG
CXXFLAGS := -g -Wall -std=c++11
CXXFLAGS += $(DEFS)
SRCS := $(wildcard ./*.cpp)
OBJS := $(patsubst %.cpp, %.o, $(SRCS))#替换的时候是%符号,不是*
LDFLAGS := -lpthread
EXE=main.out
all:$(OBJS)
$(CC) $(CXXFLAGS) $(OBJS) -o $(EXE) $(LDFLAGS)
@echo '------OK!------'
#%.o:%.c
# $(CC) -MM $(CXXFLAGS) -c $< -o $@
.PHONY:clean
clean:
-rm -f $(OBJS)
-rm -f $(EXE)
多次测试结果: