美文网首页
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++之多线程中“锁”的基本用法unique_lock比lock_guard多的功能函数

  • C++ lock_guard

    前言 lock_guard是c++11新推出的自动释放锁,基本原理就是局部对象在超出处作用域后自动销毁,并调用其析...

  • C++ lock_guard

    可能被多个线程修改的数据,我们一般用互斥量(mutex)来保护。mutex在同一时间,只能被一个线程拿到(专业术语...

  • std::unique_lock与std::lock_guard

    std::lock_guard std::lock_guard是RAII模板类的简单实现,功能简单。 std::u...

  • C++

    std::unique_lock and std::lock_guard区别: https://blog.csdn...

  • 生产者消费者中条件变量的使用

    使用的层次说明 多线程同步互斥锁mutex,lock_guard和unique_lock用法原子操作...

  • c++中lock_guard以及unique_lock的区别

    这两种锁都可以对std::mutex进行封装,实现RAII的效果。绝大多数情况下这两种锁是可以互相替代的,区别是u...

  • C++并发编程 - 互斥锁(lock_guard和unique_

    C++并发编程 - 互斥锁 在多线程的编程中,共享数据的修改限制是必不可少的环节。期望的是:当一个线程访问共享数据...

  • std::lock_guard 引起的思考

    std::lock_guard 引起的思考 版权声明:本文为 cheng-zhi 原创文章,可以随意转载,但必须在...

  • 多线程学习(五)

    unique_lock 前面有一篇讲了使用lock_guard替代lock()和unlock(),可以避免忘记un...

网友评论

      本文标题:C++ lock_guard

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