我遇到了book提供的代码示例。顺便说一句这本书有不好的评论。我很遗憾我买了它
std::mutex m_mutex;
mutable std::unique_lock<std::mutex> m_finishedQueryLock{ m_mutex, std::defer_lock };
bool m_playerQuit{ false };
void SetPlayerQuit()
{
m_finishedQueryLock.lock();
m_playerQuit = true;
m_finishedQueryLock.unlock();
}
我不满意这本书对它是如何工作的解释以及我为什么要使用它。我已经知道互斥锁如何工作及其实现,但我很难理解上面代码的第二行。为什么它有一个可变的关键字呢?
我是C ++编程的新手。因此,基本的解释水平对我有很大的帮助。
答案 0 :(得分:8)
这个例子看起来很愚蠢。
第二行是声明非静态数据成员,
mutable
(由于以下原因); std::unique_lock<std::mutex>
类型的对象,它是用于锁定/解锁关联的互斥对象的帮助程序类型; m_mutex
和特殊标记std::defer_lock
作为参数来初始化成员。但这样做是愚蠢的,如果有这样的例子,那本书就有不好评论我并不感到惊讶。
unique_lock
的要点是锁定关联的互斥锁,然后在超出范围时自动解锁。像这样创建一个unique_lock
成员是愚蠢的,因为它不会超出函数末尾的范围,因此代码绝对没有优势:
mutable std::mutex m_mutex;
bool m_playerQuit{ false };
void SetPlayerQuit()
{
m_mutex.lock();
m_playerQuit = true;
m_mutex.unlock();
}
但是这个手动解锁具有unique_lock
旨在解决的所有问题,因此它应该使用范围锁(unique_lock
或lock_guard
)但仅在函数范围内,而不是成员:
mutable std::mutex m_mutex;
bool m_playerQuit{ false };
void SetPlayerQuit()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_playerQuit = true;
} // m_mutex is automatically unlocked by the ~lock_guard destructor
mutable
关键字是必需的,以便您可以锁定const
成员函数中的互斥锁。锁定和解锁互斥锁是一种修改互斥锁的非const操作,如果它不可变,则不允许在const
成员中使用。
答案 1 :(得分:1)
unique_lock
是RAII系统。创建时,以mutex
为参数,它将锁定互斥锁,当离开范围时,它将被销毁,从而解锁互斥锁。当您需要提前解锁时,可以像示例中一样调用unlock()
函数。
使用示例中的unique_lock
并不会直接使用互斥锁创建附加值。
答案 2 :(得分:0)
所有答案都很好地解释了为什么这个例子并不好。如果您想使用from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib.parse
class oraHTTPRequestHandler(BaseHTTPRequestHandler):
def methodA(self):
self.send_response(200)
self.end_headers()
self.wfile.write('methodA'.encode('utf-8'))
return
def methodB(self):
self.send_response(200)
self.end_headers()
self.wfile.write('methodB'.encode('utf-8'))
return
def do_GET(self):
parsed_path = urllib.parse.urlparse(self.path)
if parsed_path.path.endswith('/methodA'):
self.methodA()
elif parsed_path.path.endswith('/methodB'):
self.methodB()
else:
self.send_error(501)
return
def run():
print('http server is starting...')
server_address = ('127.0.0.1', 8080)
httpd = HTTPServer(server_address, oraHTTPRequestHandler)
print('http server is running...')
httpd.serve_forever()
if __name__ == '__main__':
run()
代替std::unique_lock
,我会回答。
当线程正在等待某事时,可以使用std::lock_guard
。条件变量使用延迟锁定,因此使用std::condition_variable
,允许延迟锁定。我不认为您明确需要说您需要延迟锁定,如示例中所示。
要掌握这些概念,首先需要了解RAII是什么。然后看看this reference。可以找到条件变量的示例here。