zoukankan      html  css  js  c++  java
  • c++ 多线程笔记2

    参考:https://baptiste-wicht.com/posts/2012/03/cp11-concurrency-tutorial-part-2-protect-shared-data.html

    1.通常情况下,当你在多个线程之间使用共享对象时,需要解决同步的问题。(synchronization)

    #include <iostream>
    #include <thread>
    #include <vector>
    struct Counter 
    {
        int value;
        Counter() : value(0){}
        
        void increment()
        {
            ++value;
        }
    };
    
    int main()
    {
        Counter counter;
    
        std::vector< std::thread > threads;
        for(int i = 0; i < 5; ++i)
        {
            threads.push_back(std::thread([&counter](){
                for(int i = 0; i < 100; i++)
                {    
                    counter.increment();
                }    
            }));
        }
    
        for(auto &thread : threads)
        {
            thread.join();
        }
        std::cout << counter.value << std::endl;
        return 0;
    }
    
    /***** my output: 500 ********/

    上述代码并非原子操作(任意时刻只有一个线程对这个共享资源进行访问)。可能引入潜在的问题,交叉存取(interleave)引起的。

    /*
    *Thread 1 : read the value, get 0, add 1, so value = 1
    *Thread 2 : read the value, get 0, add 1, so value = 1
    *Thread 1 : write 1 to the field value and return 1
    *Thread 2 : write 1 to the field value and return 1
    */

    解决方法: Semaphores, Atomic reference, Monitors, Condition codes, Compare and swap, etc. 

    本文主要介绍semaphore去解决该问题,实际使用的是一种特定种类的semaphore叫做mutexes.

    一个mutex是一个非常简单的对象,只有一个线程可以获得一个互斥锁(the lock on the mutex at the same time)。

    这个简单的特性可以让我们修正这个问题。

    2.使用一个mutex确保我们的Counter 线程安全。

    c++11库中mutex包含在mutex中,mutex类: std::mutex。有两个重要的方法:

    mutex::lock() / unclock().lock()使一个线程获得这个锁,unclock()释放这个锁。

    lock()能够实现阻塞。当lock已经被得到后线程从lock()返回。

    #include <iostream>
    #include <thread>
    #include <vector>
    #include <mutex>
    
    struct Counter 
    {
        std::mutex mutex;
        int value;
        Counter() : value(0){}
        
        void increment()
        {
            mutex.lock();
            ++value;
            mutex.unlock();
        }
    };
    
    int main()
    {
        Counter counter;
    
        std::vector< std::thread > threads;
        for(int i = 0; i < 5; ++i)
        {
            threads.push_back(std::thread([&counter](){
                for(int i = 0; i < 100; i++)
                {    
                    counter.increment();
                }    
            }));
        }
    
        for(auto &thread : threads)
        {
            thread.join();
        }
        std::cout << counter.value << std::endl;
        return 0;
    }
    /*********** 能保证每次输出都为500**************/

    3.Exceptions and locks

    #include <iostream>
    #include <mutex>
    #include <thread>
    #include <vector>
    
    struct Counter
    {
        int value;
        Counter() : value(0) {}
    
        void increment()
        {
            ++value;
        }
    
        void decrement()
        {
            if(value == 0)
            {
                throw "Value cannot be less than 0";
            }
            --value;
        }
    }
    
    
    struct ConcurrentCounter //wrapper
    {
        std::mutex mutex;
        Counter counter;
    
        void increment()
        {
            mutex.lock();
            counter.increment();
            mutex.unlock();
        }
        
        void decrement()
        {
            mutex.lock();
            try {
                counter.decrement();
            } catch (std::string e) {
                mutex.unlock();
                throw e;
            }
            mutex.unclock();
        }
    };

    3. Automatic management of locks.

    当想要保护代码的某块区域时,存在一个好的解决方案去避免忘记释放lock.

    当创建std::lock_guard 后,它自动调用和释放互斥锁lock()。因此不需要2中例子处理lock() ,unlock().

    struct ConcurrentSafeCounter {
        std::mutex mutex;
        Counter counter;
    
        void increment(){
            std::lock_guard<std::mutex> guard(mutex);
            counter.increment();
        }
    
        void decrement(){
            std::lock_guard<std::mutex> guard(mutex);
            counter.decrement();
        }
    };
    The Safest Way to Get what you Want is to Try and Deserve What you Want.
  • 相关阅读:
    每日一题_191118
    每日一题_191117
    每日一题_191116
    每日一题_191115
    每日一题_191114
    每日一题_191113
    每日一题_191112
    每日一题_191111
    每日一题_191110
    一道抛物线自编题的思考
  • 原文地址:https://www.cnblogs.com/Shinered/p/9079227.html
Copyright © 2011-2022 走看看