std :: lock_guard有什么问题

时间:2018-12-31 11:11:33

标签: c++ multithreading c++11

我有简单的代码:第一个线程将std::strings推送到std::list,第二个线程从此std::strings弹出std::liststd::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(); } 有什么问题?

import re    

# just make sure all values are string type
df = df.astype(str)    

# remove the text which has word found
df.applymap(lambda x: re.sub('.*found.*','',x ))

                                          0
0  Getting links from: https://www.boo.com/
1            ├───OK─── http://www.this.com/
2              ├───OK─── http://www.is.com/
3                                          
4                                       nan
5                                       nan

1 个答案:

答案 0 :(得分:20)

您没有遵守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));
}

以使锁保护装置一直存在到区块结束为止。

并且您已经认识到(CppCoreGuidelines):

  

使用RAII锁防护(lock_guard,unique_lock,shared_lock),切勿直接调用Mutex.lock和Mutex.unlock(RAII)

如果您使用的是Microsoft Visual Studio,建议您使用代码分析并至少激活 Microsoft本机推荐规则。如果执行此操作,则会收到编译器分析警告。

  

警告C26441:保护对象必须命名(cp.44)。