精华内容
下载资源
问答
  • c++利用互斥锁实现读写锁
    千次阅读
    2018-05-27 11:13:00

    很简单就是在读的时候把写的锁锁住就好了

    class readwrite_lock  
    {  
    public:  
        readwrite_lock()  
            : read_cnt(0)  
        {  
        }  
      
        void readLock()  
        {  
            read_mtx.lock();  
            if (++read_cnt == 1)  
                write_mtx.lock();  
      
            read_mtx.unlock();  
        }  
      
        void readUnlock()  
        {  
            read_mtx.lock();  
            if (--read_cnt == 0)  
                write_mtx.unlock();  
      
            read_mtx.unlock();  
        }  
      
        void writeLock()  
        {  
            write_mtx.lock();  
        }  
      
        void writeUnlock()  
        {  
            write_mtx.unlock();  
        }  
      
    private:  
        mutex read_mtx;  
        mutex write_mtx;  
        int read_cnt; // 已加读锁个数  
    };  
    

      

    转载于:https://www.cnblogs.com/wangshaowei/p/9095438.html

    更多相关内容
  • 使用互斥锁实现读写锁

    千次阅读 2019-11-21 19:53:16
    下面是我的实现方式,如果不对。请大家指正! 首先,我百度了一个测试用例: 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

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

    展开全文
  • 两种互斥锁机制:1、synchronized2、ReentrantLockReentrantLock是jdk5的新特性,采用ReentrantLock可以完全替代替换synchronized传统的锁机制,而且采用ReentrantLock的方式更加面向对象,也更加灵活,网上有很多...

    两种互斥锁机制:

    1、synchronized

    2、ReentrantLock

    ReentrantLock是jdk5的新特性,采用ReentrantLock可以完全替代替换synchronized传统的锁机制,而且采用ReentrantLock的方式更加面向对象,也更加灵活,网上有很多关于对比两者锁方式的文章,这里就不多口舌了,大家baidu、google一下就水落石出了。在本博客中也写关于这两种锁方式实现的经典例子《生产者消费者》。

    关于读写锁,用语言解释不如直接用代码诠释,以下通过两个例子讲述读写锁以及读写锁的使用:

    例子1:

    import java.util.HashMap;

    import java.util.Map;

    import java.util.concurrent.locks.ReadWriteLock;

    import java.util.concurrent.locks.ReentrantReadWriteLock;

    /**

    * @author amber2012

    *

    * 读写锁:ReadWriteLock

    *

    * 在多线程的环境下,对同一份数据进行读写,会涉及到线程安全的问题。比如在一个线程读取数据的时候,另外一个线程在

    * 写数据,而导致前后数据的不一致性;一个线程在写数据的时候,另一个线程也在写,同样也会导致线程前后看到的数据的

    * 不一致性。

    *

    * 这时候可以在读写方法中加入互斥锁,任何时候只能允许一个线程的一个读或写操作,而不允许其他线程的读或写操作,这

    * 样是可以解决这样以上的问题,但是效率却大打折扣了。因为在真实的业务场景中,一份数据,读取数据的操作次数通常高

    * 于写入数据的操作,而线程与线程间的读读操作是不涉及到线程安全的问题,没有必要加入互斥锁,只要在读-写,写-写期

    * 间上锁就行了。

    *

    * 对于这种情况,读写锁则最好的解决方案!

    *

    * 读写锁的机制:

    * "读-读"不互斥

    * "读-写"互斥

    * "写-写"互斥

    *

    * 即在任何时候必须保证:

    * 只有一个线程在写入;

    * 线程正在读取的时候,写入操作等待;

    * 线程正在写入的时候,其他线程的写入操作和读取操作都要等待;

    *

    * 以下是一个缓存类:用于演示读写锁的操作:重入、降级

    */

    public class CachedData {

    // 缓存都应该是单例的,在这里用单例模式设计:

    private static CachedData cachedData = new CachedData();

    private final ReadWriteLock lock = new ReentrantReadWriteLock();//读写锁

    private Map cache = new HashMap();//缓存

    private CachedData(){

    }

    public static CachedData getInstance(){

    return cachedData;

    }

    // 读取缓存:

    public Object read(String key) {

    lock.readLock().lock();

    Object obj = null;

    try {

    obj = cache.get(key);

    if (obj == null) {

    lock.readLock().unlock();

    // 在这里的时候,其他的线程有可能获取到锁

    lock.writeLock().lock();

    try {

    if (obj == null) {

    obj = "查找数据库"; // 实际动作是查找数据库

    // 把数据更新到缓存中:

    cache.put(key, obj);

    }

    } finally {

    // 当前线程在获取到写锁的过程中,可以获取到读锁,这叫锁的重入,然后导致了写锁的降级,称为降级锁。

    // 利用重入可以将写锁降级,但只能在当前线程保持的所有写入锁都已经释放后,才允许重入 reader使用

    // 它们。所以在重入的过程中,其他的线程不会有获取到锁的机会(这样做的好处)。试想,先释放写锁,在

    // 上读锁,这样做有什么弊端?--如果这样做,那么在释放写锁后,在得到读锁前,有可能被其他线程打断。

    // 重入————>降级锁的步骤:先获取写入锁,然后获取读取锁,最后释放写入锁(重点)

    lock.readLock().lock();

    lock.writeLock().unlock();

    }

    }

    } finally {

    lock.readLock().unlock();

    }

    return obj;

    }

    }

    例子2:

    import java.util.Map;

    import java.util.TreeMap;

    import java.util.concurrent.locks.Lock;

    import java.util.concurrent.locks.ReadWriteLock;

    import java.util.concurrent.locks.ReentrantReadWriteLock;

    import javax.xml.crypto.Data;

    /**

    * @author amber2012

    *

    * jdk文档中关于ReentrantReadWriteLock类使用的一个很好的例子,以下是具体的介绍:

    *

    * 在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。通常,在预期 collection

    * 很大,读取者线程访问它的次数多于写入者线程,并且 entail 操作的开销高于同步开销时,这很值得一试。例如,以下

    * 是一个使用 TreeMap 的类,预期它很大,并且能被同时访问。

    */

    public class RWDictionary {

    private final Map map = new TreeMap();

    private final ReadWriteLock rwl = new ReentrantReadWriteLock();

    private final Lock readLock = rwl.readLock();

    private final Lock writeLock = rwl.writeLock();

    public Data get(String key) {

    readLock.lock();

    try {

    return map.get(key);

    } finally {

    readLock.unlock();

    }

    }

    public String[] allKeys() {

    readLock.lock();

    try {

    return (String[]) map.keySet().toArray();

    } finally {

    readLock.unlock();

    }

    }

    public Data put(String key, Data value) {

    writeLock.lock();

    try {

    return map.put(key, value);

    } finally {

    writeLock.unlock();

    }

    }

    public void clear() {

    writeLock.lock();

    try {

    map.clear();

    } finally {

    writeLock.unlock();

    }

    }

    }

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

    千次阅读 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);
    }

     

    展开全文
  • 只使用互斥锁和条件变量实现读写锁,此读写锁的实现优先考虑等待着的写入者。 1、pthread_rwlock_t数据类型 给出一个pthread_rwlock.h头文件,其中pthread_rwlock_t数据结构由一个互斥锁、一个读条件变量、一个写...
  • 一、互斥锁 互斥锁:一次最多只能有一个线程持有的锁。如Java的Lock 共享资源的使用是互斥的,即一个线程获得资源的使用权后就会将该资源加锁,使用完后会将其解锁, 如果在使用过程中有其他线程想要获取该资源的锁...
  • 只需要使用互斥锁和条件变量就能实现写者优先的读写锁。 头文件pthread_rwlock_t .h的实现: #ifdef _MY_PTHREAD_RWLOCK_H #define _MY_PTHREAD_RWLOCK_H #include #include #include #include enum{ENIVAL}; ...
  • 互斥锁、自旋锁、读写锁和文件锁互斥锁自旋锁自旋锁与互斥锁之间的区别读写锁文件锁乐观锁与悲观锁举个例子服务端是如何解决这种冲突的 互斥锁 互斥锁(mutex)又叫互斥量,从本质上说是一把锁,在访问共享资源之前...
  • 利用条件变量和互斥锁实现读写锁。 struct pthread_rwlock_t { pthread_mutex_t rw_mutex; //每一步获取读写锁,都要两次操作,上锁和解锁。每一步释放读写锁,也要两次操作,上锁和解锁。 pthread_cond_t rw_...
  • 也就是说读写锁要确保的是如下互斥关系:可以同时读,但是读-写,写-写都是互斥的;明白这一点就很好做了。读写锁的分配规则:1.只要没有线程持有某个给定的读写锁用于写,那么任意数目的线程可以持有该读写锁写锁...
  • 最近的诸多面试经历确实让...实现如下: class RWLock{ private: int state; mutex mu; condition_variable cond; public: RWLock():state(0){} void rlock(){ mu.lock(); while(state < 0){ ...
  • Golang——死锁、互斥锁读写锁实现
  • Go语言中使用sync包的Mutex类型来实现互斥锁。 使用互斥锁来修复上面代码的问题: var x int64 var wg sync.WaitGroup var lock sync.Mutex func add() { for i := 0; i < 50000; i++ { lock.Lock() // 加锁 ...
  • 互斥锁读写锁、自旋锁。这三种锁的使用以及区别将在下面一步步深入了解。 1 互斥锁 1.1 互斥锁的作用 互斥锁(也称互斥量)可以用于保护关键代码段,以确保其独占式的访问,和有点像一个二进制信号量。当进入关键...
  • (2)仅当没有线程持有某个给定的读写锁用于读或用于写,才能分配该读写锁用于写 这种给定资源的共享访问方式也叫做共享-独占上锁 因为获取一个读写锁用于读是共享锁,获取一个读写锁用于写是独占锁。 ...
  • golang互斥锁读写锁性能分析

    千次阅读 2019-04-05 21:42:20
    在并发操作中为了防止多任务同时修改共享资源导致的不确定结果,我们可能会用到互斥锁读写锁。 一:互斥锁 1.互斥锁有两种操作,获取锁和释放锁 2.当有一个goroutine获取了互斥锁后,任何goroutine都不可以获取...
  • 互斥锁读写锁的区别

    千次阅读 2018-08-19 08:59:45
    相交进程之间的关系主要有两种,同步与互斥。 所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段...
  • 互斥锁是一种「独占锁」,比如当线程 A 加锁成功后,此时互斥锁已经被线程 A 独占了,只要线程 A 没有释放手中的锁,线程 B 加锁就会失败,于是就会释放 CPU 让给其他线程,既然线程 B 释放掉了 CP
  • C++ 互斥锁源码

    2017-09-01 11:33:02
    ConsoleApp_Mutex,C++互斥锁源码cpp,可在VC++6.0或VS下直接编译运行,演示结果,控制台程序,ConsoleApp_Mutex,C++互斥锁源码cpp,可在VC++6.0或VS下直接编译运行,演示结果,控制台程序,
  • (1)只要没有线程持有某个给定的读写锁用于写,那么任意数目的线程可以持有该读写锁用于读(2)仅当没有线程持有某个读写锁用于读或用于写时,才能分配该读写锁用于写换一种说法就是,只要没有线程在修改(写)某个...
  • 锁是一个常见的同步概念,我们都听说过加锁(lock)或者解锁(unlock...也便是常说的互斥锁。 尽管名称不含lock,但是称之为锁,也是没有太大问题的。mutex无疑是最常见的多线程同步方式。其思想简单粗暴,多线程共享一
  • 互斥锁、⾃旋锁、读写锁、乐观锁、悲观锁,总结一下 互斥锁和自旋锁 最底层的就是互斥锁和自旋锁,有很多⾼级的锁都是基于它们实现的 加锁的⽬的就是保证共享资源在任意时间⾥,只有⼀个线程访问,这样就可以避免多...
  • 互斥锁 mutex:在访问共享资源之前对进行加锁操作,在访问完成之后进行解锁操作。加锁后,任何其他试图再次加锁的线程会被阻塞,直到当前进程解锁。...读写锁 rwlock(也叫作共享互斥锁:读模式共享,写模...
  • 是什么,我们为什么要用到?回到问题的本质,我们在什么场景下会用到,是在针对于公共资源,也就是临界资源的使用。对于多线程编程,当两个或多个线程同时访问或对一个临界资源操作的时候,为了防止出现数据不...
  • 并发场景中, 互斥锁读写锁 是常用解决访问冲突的两种锁: 互斥锁(Mutex) 同时只能有一个线程能够获得锁(Lock); 读写锁(RWMutex) 同时只能有一个线程能够获得写锁定(Lock); 同时能有多个线程获得读锁定(RLock)...
  • 先看看互斥锁,它只有两个状态,要么是加锁状态,要么是不加锁状态。假如现在一个线程a只是想读一个共享变量 i,因为不确定是否会有线程去写它,所以我们还是要对它进行加锁。但是这时又有一个线程b试图去读共享变量...
  • Golang互斥锁——读写锁 Golang原生支持并发应用,几乎没有其他语言默认支持如此多的并发实现工具。本文在上文的基础上讲解读写锁。 1. 互斥锁解决什么问题 我们并不希望多个线程或协程同时访问相同内存。在并发应用...
  • Python 提供的多线程模型中并没有提供读写锁读写锁相对于单纯的互斥锁,适用性更高,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁。 通俗点说就是当没有写锁时,就可以加读锁且任意...
  • 互斥锁(mutexlock): 最常使用于线程同步的锁;标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁;临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程睡眠等待锁...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 67,201
精华内容 26,880
关键字:

互斥锁实现读写锁

友情链接: feiyue.rar