精华内容
下载资源
问答
  • 利用条件变量和互斥锁实现读写锁。 struct pthread_rwlock_t { pthread_mutex_t rw_mutex; //每一步获取读写锁,都要两次操作,上锁和解锁。每一步释放读写锁,也要两次操作,上锁和解锁。 pthread_cond_t rw_...
    
    //具体参阅:《Unix网络编程》卷2,进程间通信。利用条件变量和互斥锁实现读写锁。
    
    struct pthread_rwlock_t
    {
        pthread_mutex_t rw_mutex; //每一步获取读写锁,都要两次操作,上锁和解锁。每一步释放读写锁,也要两次操作,上锁和解锁。
        pthread_cond_t rw_condreaders;
        pthread_cond_t rw_condwritres;
        int rw_magic;
        int rw_nwaitreaders;//等待获取读锁的进程。
        int rw_nwaitwriters;//等待获取写锁的进程。
        int rw_refcount;//读写锁的当前状态,-1表示它是一个写入锁(任意时刻这样的锁只能有一个),为n(n>0)时,有n个进程正在同时读。
    };
    
    //以下是实现框架。大致思路日下:先判断当前状态rw_refcount和排队等待获取锁的waiters,再决定“获取锁”或者“加入等待,条件等待”.
    
    
    //获取读锁
    void pthread_rwlock_rdlock()
    {
        result=pthread_mutex_lock(&rw->rw_mutex);
    
        while(rw->rw_refcount<0||rw->rw_nwaitwriters>0){
            rw->rw_nwaitreaders++;
            result=pthread_cond_wait(&rw->rw_condreaders,&rw->rw_mutex);
            rw->rw_nwaitreaders--;
            if(result!=0)
                break;
        }
    
        if(result==0)
            rw->rw_refcount++;
    
         result=pthread_mutex_unlock(&rw->rw_mutex);
    }
    
    
    //获取写锁
    void pthread_rwlock_rdlock()
    {
        result=pthread_mutex_lock(&rw->rw_mutex);
    
        while(rw->rw_refcount!=0){
            rw->rw_nwaitwriters++;
            result=pthread_cond_wait(&rw->rw_condwritres,&rw->rw_mutex);
            rw->rw_nwaitwriters--;
            if(result!=0)
                break;
        }
    
        if(result==0)
            rw->rw_refcount=-1;
    
         result=pthread_mutex_unlock(&rw->rw_mutex);
    
    }
    
    
    //释放读写锁。用一个统一释放函数即可。
    void pthread_rwlock_rdlock()
    {
        result=pthread_mutex_lock(&rw->rw_mutex);
    
        if(rw->rw_refcount>0)
            rw->rw_refcount--;
        else if(rw->rw_refcount==-1)
            rw->rw_refcount=0;
        else 
            throw error; //在释放锁时rw->rw_refcount=0判断条件的出现是不可能的,因为一旦加锁,它只可能两种状态,-1和1,2,3....
        
        if(rw->rw_nwaitwriters>0)//为什么要先判断是否有等待写入者,因为如果有大量的读入者试图获取锁时,可能导致写入者永远无机会获取
            if(rw->rw_refcount==0)
                result=pthread_cond_signal(&rw->rw_condwritres);//一定要先给写入者机会,否则,写入者可能没机会获取锁。
        else if(rw->rw_nwaitreaders>0)
            result=pthread_cond_broadcast(&rw->rw_condreaders);
    
    
         result=pthread_mutex_unlock(&rw->rw_mutex);
    
    }
    

    展开全文
  • 仅使用互斥锁实现读写锁

    千次阅读 2018-08-27 09:46:46
    清楚认识到读写锁分为共享锁(读锁)和独占锁(写锁),可能通过设置标志位记录读锁调用的次数结合互斥锁实现共享锁。但需要注意的是,以下的实现在多个写锁被阻塞时非常消耗计算机资源。因为线程阻塞在写锁中而没有...

    清楚认识到读写锁分为共享锁(读锁)和独占锁(写锁),可能通过设置标志位记录读锁调用的次数结合互斥锁实现共享锁。但需要注意的是,以下的实现在多个写锁被阻塞时非常消耗计算机资源。因为线程阻塞在写锁中而没有被投入睡眠,导致轮询策略。避免轮询可通过互斥锁+条件变量实现读写锁,具体实现见上一篇博文。

    以下是代码实现:

    #include<pthread.h>
    
    pthread_mutex_t rdLock = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_t wrLock = PTHREAD_MUTEX_INITIALIZER;
    int readCnt = 0;//设置读锁调用次数的标志位
    
    //实现读锁(共享锁)
    void rdLock() {
    	pthread_mutex_lock(&rdLock);
    	readCnt++;
    	if (readCnt == 1)//有人读,于是阻塞写锁
    		pthread_mutex_lock(&wrLock);
    	pthread_mutex_unlock(&rdLock);
    }
    
    void rdUnlock() {
    	pthread_mutex_lock(&rdLock);
    	readCnt--;
    	if (readCnt == 0)//表示已没有人在读,释放写锁,可以写入了
    		pthread_mutex_unlock(&wrLock);
    	pthread_mutex_unlock(&rdLock);
    }
    
    void wrLock() {
    	pthread_mutex_lock(&wrLcok);
    }
    
    void wrUnlock() {
    	pthread_mutex_unlock(&wrLock);
    }

     

    展开全文
  • 下面是我的实现方式,如果不对。请大家指正! 首先,我百度了一个测试用例: class Test { private : rw_lock rw; pthread_rwlock_t rwlock; static void* shared_task_handler(void* arg) { Test* ...

    下面是我的实现方式,如果不对。请大家指正!

    首先,我百度了一个测试用例:

    class Test
    {
    private :
        rw_lock rw;
        pthread_rwlock_t rwlock;
        
        static void* shared_task_handler(void* arg)
        {
            Test* testptr = static_cast<Test*>(arg);
            //pthread_rwlock_rdlock(&testptr->rwlock);
            testptr->rw.lock_read();
            //    do the shared task here
            pthread_mutex_lock(&cout_lock);
            cout << "read---count = " << count << endl;
            pthread_mutex_unlock(&cout_lock);
            /*if (pthread_rwlock_unlock(&testptr->rwlock) )
            {
                cout << "read unlock error " << endl;
            }*/
            testptr->rw.unlock_read();
            return NULL;
        }
        
        static void * exclusive_task_handler(void * arg)
        {
            Test* testptr = static_cast<Test*>(arg);
            //pthread_rwlock_wrlock(&testptr->rwlock);
            testptr->rw.lock_write();
            //do the exclusive task here
            pthread_mutex_lock(&cout_lock);
            ++count;
            cout << "write--count = " << count << endl;
            pthread_mutex_unlock(&cout_lock);
            /*if (pthread_rwlock_unlock(&testptr->rwlock) )
            {
                cout << "write unlock error " << endl;
            }*/
            testptr->rw.unlock_write();
            return NULL;
        
        }
    public:
        typedef void* (*ThreadFunc)(void*);
        
        void start()
        {
            srand(time(NULL));
            /*if( pthread_rwlock_init(&rwlock,NULL) )
            {
                cout << "rwlock init error " << endl;
            }*/
            rw.rw_lock_init();  //初始化读写锁
            const int THREADS_NO = rand()%100;
            pthread_t* threads = new pthread_t[THREADS_NO];
            for(int i = 0; i < THREADS_NO; ++i)
            {
                ThreadFunc tmpfunc = rand() % 2 ? shared_task_handler : exclusive_task_handler;
                if (pthread_create(threads+i,NULL,tmpfunc,this))
                {
                    cerr << "pthread_create fails" << endl;
                    exit(1);
                }
            }
            
            for(int i=0; i<THREADS_NO; i++)
            {
                pthread_join(threads[i],NULL);
            }
            delete[] threads;
            //pthread_rwlock_destroy(&rwlock);
        }
    };
    int main()
    {
        Test tmptest;
        tmptest.start();
        pthread_mutex_destroy(&cout_lock);        //这里加一个输出锁,是为了防止读写输出到终端的时候有竞争
    }

    这个测试用例说的是,当读的时候就会输出count的值,写的时候,就会++count,并且输出它的值,

    这是系统测试的结果:

    图片

    然后,我自己实现了用互斥锁实现读写锁:

    #include <pthread.h>
    #include <cstdlib>
    #include <ctime>
    #include <iostream>
    using namespace std;
    
    static int count = 0;
    pthread_mutex_t cout_lock=PTHREAD_MUTEX_INITIALIZER;        //输出到终端避免竞争的锁
    
    class rw_lock
    {
    public:
        rw_lock(){};
        
    
        ~rw_lock()
        {
            pthread_mutex_destroy(&my_lock);
            pthread_mutex_destroy(&atom);
        };
    
    
    
    public:
    
        void rw_lock_init(){
            pthread_mutex_init(&my_lock,NULL);
            pthread_mutex_init(&atom,NULL);        //为了实现read_num++,防止同时多个read竞争而使用的锁
            read_num=0;
            write_num=0;
        }
    
        void lock_read(){
            while(write_num>0)        //说明正在写,阻塞读
            {
                pthread_mutex_lock(&my_lock);
            }
            pthread_mutex_lock(&atom);        //这里的锁,只是为了原子操作,避免多个竞争
            read_num++;
            pthread_mutex_unlock(&atom);
        }
    
        void unlock_read(){
            pthread_mutex_lock(&atom);
            read_num--;
            if (read_num==0&&write_num==0)
            {
                pthread_mutex_unlock(&my_lock);        //如果没有读写了,说明可以接下来既可以读有可以写,从
                                                       //而解锁
            }
            pthread_mutex_unlock(&atom);
            
        }
    
        void lock_write(){
            while(read_num+write_num>0)        //当有读和写时,就和iu阻塞,因为写不能与其他人共存
            {
                pthread_mutex_lock(&my_lock);
            }
            pthread_mutex_lock(&atom);
            write_num++;
            pthread_mutex_unlock(&atom);
            
        }
    
        void unlock_write(){
            pthread_mutex_lock(&atom);
            write_num--;
            if (write_num==0)        //没有写了,从而接下来就可以读或写了,从而开放临界区
            {
                pthread_mutex_unlock(&my_lock);
            }
            pthread_mutex_unlock(&atom);
        }
    
    private:
        pthread_mutex_t my_lock;
        pthread_mutex_t atom;
        int read_num;
        int write_num;
      
    };
    

    输出结果是:

    图片2

    自我感觉应该是没问题的,只不过还没有更好的测试用例来测试我写的锁;

    展开全文
  • #include <bits/stdc++.h> using namespace std; class RWlock{ public: RWlock(int state_):state(state_){} void rlock(){ unique_lock<mutex> lck(mtx); while(state<0){ ...
    #include <bits/stdc++.h>
    using namespace std;
    class RWlock{
    public:
        RWlock(int state_):state(state_){}
        void rlock(){
            unique_lock<mutex> lck(mtx);
            while(state<0){
                cond.wait(lck);
            }
            state++;
        }
        void unrlock(){
            unique_lock<mutex> lck(mtx);
            if(--state==0) cond.notify_one();
        }
        void wlock(){
            unique_lock<mutex> lck(mtx);
            while(state!=0) cond.wait(lck);
            state--;
        }
        void unwlock(){
            unique_lock<mutex> lck(mtx);
            state=0;
            cond.notify_all();
        }
    private:
        mutex mtx;
        int state;
        condition_variable cond;
    };
    
    展开全文
  • 很简单就是在读的时候把写的锁锁住就好了 class readwrite_lock { public: readwrite_lock() : read_cnt(0) { } void readLock() { read_mtx.lock(); ...
  • 本博客致力于方便 程序员 交流 各类程序问题 主要是笔试面试题目 及经验), 参与方式:  各位请投稿到 hackjobswww@gmail.com  , 标题参考格式:  xxx大学 - xxx公司  ... ( 如果能附上自己对题
  • 锁—互斥锁 VS 读写锁 11、概念: 独享锁/共享锁就是一种广义的说法,互斥锁/读写锁就是具体的实现互斥锁在Java中的具体实现就是ReentrantLock。 读写锁在Java中的具体实现就是ReadWriteLock。
  • Golang互斥锁——读写锁 Golang原生支持并发应用,几乎没有其他语言默认支持如此多的并发实现工具。本文在上文的基础上讲解读写锁。 1. 互斥锁解决什么问题 我们并不希望多个线程或协程同时访问相同内存。在并发应用...
  • 27. 互斥锁读写锁

    2020-07-07 15:46:50
    文章目录Golang 锁互斥锁读写锁 ...在Go中,sync.Mutex 提供了互斥锁实现。 简单使用示例: func main() { var mutex sync.Mutex count := 0 for r := 0; r < 50; r++ { go func() { mutex.Lock() count += 1
  • golang中sync包实现了两种锁Mutex (互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能.type Mutexfunc (m *Mutex) Lock()func (m *Mutex) Unlock()type RWMutexfunc ...
  • golang 互斥锁读写锁

    2018-01-19 15:38:00
    golang中sync包实现了两种锁Mutex(互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能。 type Mutex func (m *Mutex) Lock() func (m *Mutex) Unlock() ...
  • 1.独享锁/共享锁是一种广义的说法,互斥锁/读写锁,就是具体的实现。 2.一次只能一个线程拥有互斥锁,其他线程只有等待 3.互斥锁在Java中的具体实现就是ReentrantLocak 4.读写锁在Java中的具体实现就是ReadWriteLock...
  • 互斥锁/读写锁

    2021-01-05 17:58:02
    互斥锁 Linux中提供一把互斥锁mutex(也称之为互斥量)。每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。 资源还是共享的,线程间也还是竞争的,但通过“锁”就将资源的访问变成互斥操作,...
  • ###互斥锁其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许...
  • golang互斥锁读写锁

    2018-07-27 21:42:07
    golang中sync包实现了两种锁Mutex (互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能. 1、互斥锁 其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()...
  • 自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步的锁;标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁;临界区和互斥量都可用来实现此锁,通常...
  • gorouting的互斥锁读写锁 互斥锁 互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个 goroutine 可以访问共享资源。Go 语言中使用 sync 包的 Mutex 类型来实现互斥锁. 使用互斥锁能够保证同一...
  • Go语言中使用sync包的Mutex类型来实现互斥锁。 使用互斥锁来修复上面代码的问题: var x int64 var wg sync.WaitGroup var lock sync.Mutex func add() { for i := 0; i < 50000; i++ { lock.Lock() // 加锁 ...
  • 互斥锁读写锁使用

    2017-11-28 20:51:24
    概述sync.Mutex和sync.RWMutex是Go语言底层基础对象,用于构建多个goroutine间的同步逻辑,当多个协程需要对共享数据读写时用到。具体实现极为简洁,性能...代码互斥锁 func print(t *testing.T, i int, wg *sync.WaitG
  • 互斥锁(mutexlock):最常使用于线程同步的锁;标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁;临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程睡眠等待锁...
  • Go语言中可以使用sync包的Mutex类型来实现互斥锁。 例: // 开启多个gorourtine执行add()操作,会导致两个goroutine读取到相同的x导致最终结果偏小 var x = 0 var wg sync.WaitGroup func add() { defer wg.Done()...
  • java.util.concurrent.locks包提供了锁和等待条件的接口和类, 可用于替代JDK1.5之前的同步...互斥锁--Lock接口及其实现类ReentrantLock 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们...
  • 要知道的是在 Go 语言中,信道的地位非常高,面对并发问题,我们始终应该优先考虑使用信道。 但是如果通过信道解决不了的,不得不使用共享内存来实现并发编程的... 一个叫RWMutex,利用它可以实现读写锁互斥锁 ...
  • 互斥锁读写锁和自旋锁的区别

    千次阅读 2019-02-14 18:04:25
    读写锁特点: 读写锁有三种状态:读加锁状态、写加锁状态和不加锁状态  只有一个线程可以占有写状态的锁,但可以有多个线程同时占有读状态锁,这也是它可以实现高并发的原因。当其处于写状态锁下,...
  • 读写锁特点: 1)多个读者可以同时进行读 ...互斥锁是在抢锁失败的情况下主动放弃CPU进入睡眠状态直到锁的状态改变时再唤醒,而操作系统负责线程调度,为了实现锁的状态发生改变时唤醒阻塞的...
  • 读写锁遵循的访问控制规则与互斥锁有所不同。 在读写锁管辖的范围内,它允许任意个读操作的同时进行。但是,在同一时刻,它只允许有一个写操作在进行。并且,在某一个写操作被进行的过程中,读操作的进行也是不被...
  • 互斥锁 在多线程的情况下,当一个变量可以被多个线程修改时,就需要考虑多线程同步问题。线程A修改变量前,先加锁,修改结束再解锁,然后线程B获取同样的锁,修改结束再解锁,如果不是同一把锁,同步是无效的。 在...
  • 互斥锁(mutexlock): 最常使用于线程同步的锁;标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁;临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程睡眠等待锁...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,270
精华内容 508
关键字:

互斥锁实现读写锁