C/C++编程:pthread_mutex_t封装&thread_mutex_guard的实现

1060 篇文章 293 订阅

封装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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值