C++ lock_guard

2019-04-04  本文已影响0人  louyang

可能被多个线程修改的数据,我们一般用互斥量(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,----
上一篇下一篇

猜你喜欢

热点阅读