封装pthread_mutex
//
// Created by oceanstar on 2021/8/9.
//
#ifndef OCEANSTAR_HTTP_THREAD_MUTEX_H
#define OCEANSTAR_HTTP_THREAD_MUTEX_H
#include <noncopyable.h>
#include <bits/pthreadtypes.h>
namespace oceanstar{
/**
* 线程互斥锁: 封装C语言的pthread_mutex,两者功能相同,但是由C变成Cpp类
*/
class thread_mutex : public noncopyable{
public:
/**
* 构造方法
* @param recursive {bool} 是否启用递归锁方式
*/
thread_mutex(bool recursive = true);
~thread_mutex(void);
/**
* 对线程锁进行加锁,一直到加锁成功或内部失败(一般不会失败,除非是系统问题)
* @return {bool} 返回 false 说明线程锁有问题
*/
bool lock(void);
/**
* 尝试性加锁,无论成功与否都会立即返回
* @return {bool} 返回 true 表示加锁成功,返回 false 表示加锁失败
*/
bool try_lock(void);
/**
* 解线程锁
* @return {bool} 返回 false 表示解锁失败,有可能之前并未加锁成功所致
*/
bool unlock(void);
/**
* 获得 acl 中 C 版本的系统类型的线程锁
* @return {acl_pthread_mutex_t*}
*/
pthread_mutex_t* get_mutex(void) const;
private:
pthread_mutex_t* mutex_;
pthread_mutexattr_t mutex_attr_;
};
}
#endif //OCEANSTAR_HTTP_THREAD_MUTEX_H
//
// Created by oceanstar on 2021/8/9.
//
#include <cstdlib>
#include <pthread.h>
#include <cstring>
#include <cerrno>
#include <log.h>
#include "thread_mutex.h"
namespace oceanstar{
thread_mutex::thread_mutex(bool recursive /* = true */){
mutex_ = (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t));
int ret = pthread_mutexattr_init(&mutex_attr_);
if (ret) {
logger_fatal("pthread_mutexattr_init error=%s", strerror(errno));
}
if (recursive && (ret = pthread_mutexattr_settype(&mutex_attr_,PTHREAD_MUTEX_RECURSIVE))) {
logger_fatal("pthread_mutexattr_settype error=%s", strerror(errno));
}
ret = pthread_mutex_init(mutex_, &mutex_attr_);
if (ret) {
logger_fatal("pthread_mutex_init error=%s", strerror(errno));
}
}
thread_mutex::~thread_mutex(void){
(void) pthread_mutexattr_destroy(&mutex_attr_);
}
pthread_mutex_t* thread_mutex::get_mutex(void) const
{
return mutex_;
}
bool thread_mutex::lock(void)
{
int ret = pthread_mutex_lock(mutex_);
if (ret) {
logger_error("pthread_mutex_lock error %s", strerror(errno));
return false;
}
return true;
}
bool thread_mutex::try_lock(void)
{
return pthread_mutex_trylock(mutex_) == 0;
}
bool thread_mutex::unlock(void)
{
int ret = pthread_mutex_unlock(mutex_);
if (ret) {
logger_error("pthread_mutex_unlock error %s", strerror(errno));
return false;
}
return true;
}
}
测试
#include <iostream>
#include <pthread.h>
#include <thread_mutex.h>
#include <thread>
#include <mutex>
int a = 0;
void thread_tast(oceanstar::thread_mutex *lock){
for(int i = 0; i < 100000; i++){
lock->lock();
a++;
lock->unlock();
}
printf("a = %d\n", a); // 锁能够保证最终结果一定相同(但不保证过程),如果不加锁的话每次运行结果都不一样
}
int main() {
// std::mutex * lock= new std::mutex ;
oceanstar::thread_mutex *lock = new oceanstar::thread_mutex();
std::thread t1(thread_tast, lock);
std::thread t2(thread_tast, lock);
t1.detach();
t2.detach();
getchar();
return 0;
}
锁仅仅保证结果一定对,但是不保证过程
实现thread_mutex_guard
原理:析构函数的调用
namespace oceanstar{
class thread_mutex_guard : public noncopyable
{
public:
thread_mutex_guard(thread_mutex& mutex);
~thread_mutex_guard(void);
private:
thread_mutex& mutex_;
};
}
namespace oceanstar{
thread_mutex_guard::thread_mutex_guard(thread_mutex& mutex)
: mutex_(mutex)
{
if (!mutex_.lock()) {
logger_fatal("lock error=%s", strerror(errno));
}
}
thread_mutex_guard::~thread_mutex_guard(void)
{
if (!mutex_.unlock()) {
logger_fatal("unlock error=%s", strerror(errno));
}
}
}
测试
#include <iostream>
#include <thread_mutex.h>
#include <thread>
#include <mutex>
oceanstar::thread_mutex lock ;
int a = 0;
void thread_tast(){
for(int i = 0; i < 100000; i++){
oceanstar::thread_mutex_guard mutexGuard(lock);
a++;
}
printf("a = %d\n", a); // 锁能够保证最终结果一定相同(但不保证过程),如果不加锁的话每次运行结果都不一样
}
int main() {
std::thread t1(thread_tast);
std::thread t2(thread_tast);
t1.detach();
t2.detach();
getchar();
return 0;
}