当前位置: 首页 > news >正文

对锁进行封装

目录

锁的封装

makefile编写

测试运行

RAII式封装


我们今天学习对锁进行封装。

我们在命名空间里面,在自己构建的类mutex里面完成对锁的封装。

锁的封装

我们要进行动态初始化锁,首先要有一个锁对象,所以mutex类里面的私有成员就是锁对象了,然后载初始化里面调用pthread_mutex_init进行初始化,析构函数里面调用pthread_mutex_destroy进行销毁,对锁的操作只需要有解锁和加锁,所以在成员函数lock里面调用pthread_mutex_lock进行加锁,所以在成员函数unlock里面调用pthread_mutex_unlock进行解锁。

#ifndef _THREAD_HPP__
#define _THREAD_HPP__

#include<iostream>
#include<pthread.h>
using namespace std;

//对锁进行封装

namespace lockmodule
{
    class mutex
    {
    public:
        
        mutex()
        {
            int n = pthread_mutex_init(&_lock, nullptr);
            (void)n;
        }
        void lock()
        {
            int n = pthread_mutex_lock(&_lock);
            (void)n;
        }
        void unlock()
        {
            int n = pthread_mutex_unlock(&_lock);
            (void)n;
        }
        ~mutex()
        {
            int n = pthread_mutex_destroy(&_lock);
            (void)n;
        }

    private:
        pthread_mutex_t _lock;
    };

};

#endif

很简单吧,但是由于之前讲过一块临界资源只能有一个锁的,所有线程都只能调用或者间接指向这个锁,所以为了防止锁被拷贝,所以需要将拷贝构造和拷贝赋值给禁用

class mutex
    {
    public:
        mutex(const mutex&) = delete;
        mutex(mutex&&) = delete; //禁止移动拷贝
        const mutex& operator= (const mutex&) = delete;
        const mutex& operator= (mutex&&) = delete; //禁止移动拷贝
        mutex()
        {
            int n = pthread_mutex_init(&_lock, nullptr);
            (void)n;
        }

右值的拷贝构造和赋值可以不用,基本没有人会这么调用。

makefile编写

BIN=ticket
CC=g++
SRC = $(wildcard *.cc) 
OBJ = $(SRC:.cc=.o)

$(BIN):$(OBJ)
	$(CC) -o $@ $^ -std=c++17 -lpthread
%.o:%.cc
	$(CC) -c $< 
.PTHONY:clean
clean:
	rm -f $(BIN) $(OBJ)

%.o:%.cc这里即使 OBJ 中列出了 .o 文件,make 仍然需要知道如何生成它们, 这行就是在指导make如何生成.o的

OBJ这里:前面的这个范围集合不能有空格。

测试运行

测试代码依旧用的是之间的抢票程序的逻辑,只不过有少许修改。

#include"mutex.hpp"
using namespace lockmodule;
int ticket = 1000;
mutex mtx;
void *route(void *arg)
{
    char *id = (char *)arg;
    while (1)
    {
        mtx.lock();
        if (ticket > 0)
        {
            usleep(1000);
            printf("%s sells ticket:%d\n", id, ticket);
            ticket--;
            mtx.unlock();
        }
        else
        {
            mtx.unlock();
            break;
        }
    }
    return nullptr;
}
int main()
{
    pthread_t t1, t2, t3, t4;
    pthread_create(&t1, NULL, route, (void*)"thread 1");
    pthread_create(&t2, NULL, route, (void*)"thread 2");
    pthread_create(&t3, NULL, route, (void*)"thread 3");
    pthread_create(&t4, NULL, route, (void*)"thread 4");
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);
    pthread_join(t4, NULL);
}

RAII式封装

我们还可以仿造RAII的形式对锁进行保护,加一个保护类,私有成员自然是这个锁了,然后将一个锁的加锁和解锁分别放在一个这个类的构造和析构函数里面,然后在while循环里面构造保护类的对象,此时由于由于保护类对象属于这个循环区域的,刚刚创建出来的时候会之间构造,调用保护类构造函数加锁之前会先构造这个锁,完成加锁,然后等出了循环自动释放调用析构函数解锁,并调用锁本身的析构函数释放锁资源,从而实现自动加锁+自动释放的RAII形式。

 class lockguard
    {
    public:
        lockguard(mutex& mut)
           :_mut(mut)
        {
            mut.lock();
        }
        ~lockguard()
        {
            _mut.unlock();
        }
    private:
        mutex& _mut;
    };
};
#include"mutex.hpp"
using namespace lockmodule;
int ticket = 1000;
mutex mtx;
void *route(void *arg)
{
    char *id = (char *)arg;
    while (1)
    {
        lockguard guard(mtx);
        if (ticket > 0)
        {
            usleep(1000);
            printf("%s sells ticket:%d\n", id, ticket);
            ticket--;
        }
        else
        {
            break;
        }
    }
    return nullptr;
}

相关文章:

  • 通义Qwen实战(2): vllm框架部署实战
  • Yolo系列之Yolo v1概述及网络结构理解
  • C —— 指针和数组的面试题
  • Scala 之 正则
  • 安科瑞微电网能量管理控制箱,光伏发电的守护者
  • 【蓝桥杯】重点冲刺
  • 打破传统查询瓶颈:深入解析MySQL 8.0 LATERAL JOIN的实战价值
  • Oracle初识:登录方法、导入dmp文件
  • 【深度学习新浪潮】图像修复(Image Inpainting)技术综述:定义、进展与应用展望
  • 第十六届蓝桥杯模拟二(串口通信)
  • 文献笔记 - Analysis of Ground Effect for Small-Scale UAVs in Forward Flight
  • 设计秒杀系统(高并发的分布式系统)
  • 20250327解决在立创eda中铺了GND的铜之后仍显示部分地线未连接
  • Vue3.5 企业级管理系统实战(十):面包屑导航组件
  • FFmpeg学习:AVPacket结构体
  • 谷歌Chrome浏览器零日漏洞遭黑客大规模利用
  • Nginx 学习笔记
  • 华为eNSP-配置静态路由与静态路由备份
  • FALL靶机
  • 双目云台摄像头全方位监控方案
  • 平面设计高端网站/今日全国疫情最新消息
  • 什么做婚车网站最大/深圳seo排名
  • 深圳宝安企业网站建设/培训心得体会1000字通用
  • tp框架做商城网站怎么用缓存/市场营销培训
  • 电子商务网站的推广方法/seo排名教程
  • 抓取网站后台/中国十大搜索引擎排名