【Linux】锁的简单封装以及原理解析


风晓
风晓 2024-01-06 11:32:06 50922 赞同 0 反对 0
分类: 资源
一、锁的原理 为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性,即使是多处理器平台,访问内存的 总线周期也有先后,一个处理器上的交换指令执行时另一个处理器的交换指令只能等待总线周期。

 

锁其实也属于共享资源,因为可以被所有线程看到,但锁的申请与销毁是具有原子性的,下面我们看一下原理

 

过程1:


过程2


过程3


过程4

本质:把一个共享的锁,让一个线程以一条汇编的方式,交换到自己的硬件上下文中

二、 锁的简单封装
1.LockGuard.hpp
class Mutex{
public:
Mutex(pthread_mutex_t *lock)
:lock_(lock){}

void Lock(){
    pthread_mutex_lock(lock_);
}

void Unlock(){
        pthread_mutex_unlock(lock_);
}

~Mutex(){}

private:
    pthread_mutex_t *lock_;
};

 


class LockGuard{//类似智能指针的玩法
//出了作用域自动析构
public:
LockGuard(pthread_mutex_t *lock)
:mutex_(lock)
{
mutex_.Lock();
}

~LockGuard(){
    mutex_.Unlock();
}
private :
Mutex mutex_;
};


2.使用
#include<iostream>
 #include<unistd.h>
 #include<pthread.h>
 #include<string>
 #include<vector>
 #include"LockGuard.hpp"
 using namespace std;

#define NUM 4

pthread_mutex_t lock;


class threadData{
public:
    threadData(int number){
        threadname="thread-"+to_string(number);
    }
public:
string threadname;

};

int ticket=300;


void *getTicket(void*args){
    threadData*td=static_cast<threadData*>(args);
    const char*name=td->threadname.c_str();

    while(true){
 
        pthread_mutex_lock(&lock);
        if(ticket>0){
            usleep(1000);
            printf("who=%s get ticket :%d \n ",name ,ticket);
            ticket--;
            pthread_mutex_unlock(&lock);
        }
        else {
            pthread_mutex_unlock(&lock);
            break;
        }
            
        usleep(13);

    }
    printf("%s.....quit",name);
    return nullptr;
}

int main(){
    vector<pthread_t> tids;
    vector<threadData *> thread_datas;
    for (int i = 1; i <= NUM; i++)
    {
        pthread_t tid;
        threadData *td = new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid, nullptr, getTicket, thread_datas[i - 1]);
        tids.push_back(tid);
    }


    for(auto thread:tids){
        pthread_join(thread,nullptr);
    }

    for (auto td:thread_datas){
        delete td;
    }

    return 0;
}


1.正常锁的使用


2.使用封装后的


总结
1.申请锁和释放锁本身就被设计成了原子性操作
2.当线程访问临界区的过程,对于其他线程是原子的(对于其他线程来讲,一个线程要么没有锁,要么释放锁)。
3.在临界区中,线程可以被切换,(在线程被切出去的时候,是持有锁被切走的,我不在期间,你们没有锁,照样不能访问临界资源!!!!)
4.线程独立的资源:线程的栈和线程的硬件上下文

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
风晓L1
粉丝 1 资源 2038 + 关注 私信
最近热门资源
银河麒麟桌面操作系统备份用户数据  127
统信桌面专业版【全盘安装UOS系统】介绍  122
银河麒麟桌面操作系统安装佳能打印机驱动方法  114
银河麒麟桌面操作系统 V10-SP1用户密码修改  105
最近下载排行榜
银河麒麟桌面操作系统备份用户数据 0
统信桌面专业版【全盘安装UOS系统】介绍 0
银河麒麟桌面操作系统安装佳能打印机驱动方法 0
银河麒麟桌面操作系统 V10-SP1用户密码修改 0
作者收入月榜
1

prtyaa 收益393.62元

2

zlj141319 收益218元

3

1843880570 收益214.2元

4

IT-feng 收益209.03元

5

风晓 收益208.24元

6

777 收益172.71元

7

Fhawking 收益106.6元

8

信创来了 收益105.84元

9

克里斯蒂亚诺诺 收益91.08元

10

技术-小陈 收益79.5元

请使用微信扫码

加入交流群

请使用微信扫一扫!