gpt4 book ai didi

c++ - std::lock_guard 有什么问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:51:53 24 4
gpt4 key购买 nike

我有简单的代码:第一个线程将 std::strings 推送到 std::list,第二个线程弹出 std::strings 从这个 std::list。所有 std::list 的操作都受到 std::mutex m 的保护。此代码将错误永久打印到控制台:"Error: lst.begin() == lst.end()"

如果我将 std::lock_guard 替换为构造 m.lock()m.unlock() 代码将开始正常工作。 std::lock_guard 有什么问题?

#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <string>

std::mutex m;
std::list<std::string> lst;

void f2()
{
for (int i = 0; i < 5000; ++i)
{
std::lock_guard<std::mutex> { m };
lst.push_back(std::to_string(i));
}

m.lock();
lst.push_back("-1"); // last list's element
m.unlock();
}

void f1()
{
std::string str;

while (true)
{
m.lock();
if (!lst.empty())
{
if (lst.begin() == lst.end())
{
std::cerr << "Error: lst.begin() == lst.end()" << std::endl;
}
str = lst.front();
lst.pop_front();
m.unlock();
if (str == "-1")
{
break;
}
}
else
{
m.unlock();
std::this_thread::yield();
}
}
}

// tested in MSVS2017
int main()
{
std::thread tf2{ f2 };
f1();
tf2.join();
}

最佳答案

你没有服从CppCoreGuidelines CP.44: Remember to name your lock_guards and unique_locks :).

for (int i = 0; i < 5000; ++i)
{
std::lock_guard<std::mutex> { m };
lst.push_back(std::to_string(i));
}

您只是在创建一个临时的 std::lock_guard 对象,该对象会立即创建和销毁。您需要像中那样命名对象

{
std::lock_guard<std::mutex> lg{ m };
lst.push_back(std::to_string(i));
}

这样锁守卫就会一直存在到 block 的末尾。

正如您已经认识到的 ( CppCoreGuidelines ):

Use RAII lock guards (lock_guard, unique_lock, shared_lock), never call mutex.lock and mutex.unlock directly (RAII)

如果您使用的是 Microsoft Visual Studio,我建议您使用代码分析并至少激活 Microsoft Native Recommended Rules。如果这样做,您将收到编译器分析警告。

warning C26441: Guard objects must be named (cp.44).

关于c++ - std::lock_guard 有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53986760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com