std::lock
STD::锁
Defined in header | | |
---|---|---|
template< class Lockable1, class Lockable2, class... LockableN > void lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn | | (since C++11) |
锁定给定Lockable
对象lock1
,,,lock2
,,,...
,,,lockn
使用死锁避免算法来避免死锁。
对象被一系列未指定的调用锁定。lock
,,,try_lock
,,,unlock
.如果打电话给lock
或unlock
结果是一个例外,unlock
在重新抛出之前,对任何锁定对象调用。
参数
lock1, lock2, ... , lockn | - | the Lockable objects to lock |
---|
返回值
%280%29
注记
Boost提供了此函数的一个版本。这需要一系列的Lockable
由一对迭代器定义的对象。
例
下面的示例使用std::lock
锁对互斥锁而不死锁。
二次
#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <string>
struct Employee {
Employee(std::string id) : id(id) {}
std::string id;
std::vector<std::string> lunch_partners;
std::mutex m;
std::string output() const
{
std::string ret = "Employee " + id + " has lunch partners: ";
for( const auto& partner : lunch_partners )
ret += partner + " ";
return ret;
}
};
void send_mail(Employee &, Employee &)
{
// simulate a time-consuming messaging operation
std::this_thread::sleep_for(std::chrono::seconds(1)
}
void assign_lunch_partner(Employee &e1, Employee &e2)
{
static std::mutex io_mutex;
{
std::lock_guard<std::mutex> lk(io_mutex
std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
}
// use std::lock to acquire two locks without worrying about
// other calls to assign_lunch_partner deadlocking us
{
std::lock(e1.m, e2.m
std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock
std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock
// Equivalent code (if unique_locks are needed, e.g. for condition variables)
// std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock
// std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock
// std::lock(lk1, lk2
{
std::lock_guard<std::mutex> lk(io_mutex
std::cout << e1.id << " and " << e2.id << " got locks" << std::endl;
}
e1.lunch_partners.push_back(e2.id
e2.lunch_partners.push_back(e1.id
}
send_mail(e1, e2
send_mail(e2, e1
}
int main()
{
Employee alice("alice"), bob("bob"), christina("christina"), dave("dave"
// assign in parallel threads because mailing users about lunch assignments
// takes a long time
std::vector<std::thread> threads;
threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob)
threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob)
threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice)
threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob)
for (auto &thread : threads) thread.join(
std::cout << alice.output() << '\n' << bob.output() << '\n'
<< christina.output() << '\n' << dave.output() << '\n';
}
二次
可能的产出:
二次
alice and bob are waiting for locks
alice and bob got locks
christina and bob are waiting for locks
christina and bob got locks
christina and alice are waiting for locks
christina and alice got locks
dave and bob are waiting for locks
dave and bob got locks
Employee alice has lunch partners: bob christina
Employee bob has lunch partners: alice christina dave
Employee christina has lunch partners: bob alice
Employee dave has lunch partners: bob
二次
另见
try_lock (C++11) | attempts to obtain ownership of mutexes via repeated calls to try_lock (function template) |
---|
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。