美文网首页
C++ lock_guard

C++ lock_guard

作者: louyang | 来源:发表于2019-04-04 16:36 被阅读0次

    可能被多个线程修改的数据,我们一般用互斥量(mutex)来保护。
    mutex在同一时间,只能被一个线程拿到(专业术语叫lock), 其他试图lock mutex的线程会被挂起,直到该mutex被释放后,才有可能拿到mutex并继续执行。

    先看一个没有mutex的例子:

    #include <thread>
    #include <iostream>
    
    int global = 0;
    
    void threadTask()
    {
        for (int i = 0; i < 100000000; i++) {
            global++;
        }
        std::cout << global << std::endl;
    }
    
    int main()
    {
        std::thread t1(threadTask);
        std::thread t2(threadTask);
        std::thread t3(threadTask);
    
        t1.join();
        t2.join();
        t3.join();
    }
    

    运行结果:

    $ g++ a.cpp -lpthread
    $ ./a.out
    300000000
    $ ./a.out
    297532046
    

    这个程序有3个线程,每个线程各做1亿次自加。因为没有mutex保护,运行结果并不总是3亿。

    再看一个例子:

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <list>
    #include <algorithm>
    #include <mutex>
    
    std::list<int>myList;
    std::mutex myMutex;
    using namespace std::chrono_literals;
    
    void addToList(int data)
    {
        std::lock_guard<std::mutex> guard(myMutex);
        myList.push_back(data);
    }
    
    void addThread(int max, int interval)
    {
        for (int i = 0; i < max; i++) {
            if( (i % interval) == 0) {
                addToList(i);
            }
            std::this_thread::sleep_for(1s);
        }
    }
    
    void printList()
    {
        std::lock_guard<std::mutex> guard(myMutex);
        for (auto i : myList) {
            std::cout << i << ",";
        }
        std::cout << "----" << std::endl;
    }
    
    void printThread()
    {
        for (int i = 0; i < 100; i++) {
            printList();
            std::this_thread::sleep_for(1s);
        }
    }
    
    int main()
    {
        int max = 100;
    
        std::thread t1(addThread, max, 1);
        std::thread t2(addThread, max, 10);
        std::thread t3(printThread);
    
        t1.join();
        t2.join();
        t3.join();
    
        return 0;
    }
    
    $ g++ a.cpp -lpthread && ./a.out
    ----
    0,0,----
    0,0,1,----
    0,0,1,2,----
    0,0,1,2,3,----
    0,0,1,2,3,4,----
    0,0,1,2,3,4,5,----
    0,0,1,2,3,4,5,6,----
    0,0,1,2,3,4,5,6,7,----
    0,0,1,2,3,4,5,6,7,8,----
    0,0,1,2,3,4,5,6,7,8,9,10,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,18,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,18,19,20,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,18,19,20,20,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,18,19,20,20,21,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,18,19,20,20,21,22,----
    0,0,1,2,3,4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,18,19,20,20,21,22,23,----
    

    相关文章

      网友评论

          本文标题:C++ lock_guard

          本文链接:https://www.haomeiwen.com/subject/vgrqiqtx.html