Mutex篇续
上一篇传送门
std::unique_lock::try_lock_until
template<typename Clock, typename Duration> bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time);
尝试调用unique_lock所管理的对象(注:该对象也必须支持try_lock_until)的try_lock_until(abs_time)给所管理的互斥量上锁.
(注:try_lock_until函数接受一个时间点(abs_time)作为参数.在指定的时间点到来之前当前线程中的unique_lock管理的mutex未获得线程锁,那么当前线程就会被阻塞(blocking),如果在到达时间点之前为能给所管理的互斥量上锁那么返回false.上锁了就返回true.)
std::unique_lock::unlock
void unlock();
调用被管理的mutex的unlock()函数,解锁被管理的mutex,并把unique_lock对该mutex的拥有权设置为false.
std::unique_lock::relase
mutex_type* relase()noexcept;
该函数返回被unique_lock管理的mutex对象的指针,不再拥有该mutex的管理权,如果该mutex在被unique_lock管理的时候被上锁了,该mutex被relase出来的时候仍然是lock的,需要被unlock.
// unique_lock::release example #include <iostream> // std::cout #include <vector> // std::vector #include <thread> // std::thread #include <mutex> // std::mutex, std::unique_lock
std::mutex mtx; int count = 0;
void print_count_and_unlock (std::mutex* p_mtx) { std::cout << "count: " << count << '\n'; p_mtx->unlock(); }
void task() { std::unique_lock<std::mutex> lck(mtx); ++count; print_count_and_unlock(lck.release()); //由于前面已经用unique_lock对mtx上锁了纵然释放了对mtx的所有权,mtx仍然是被锁住的. }
int main () { std::vector<std::thread> threads; for (int i=0; i<10; ++i) threads.emplace_back(task); //注意这里的emplace_back.
for (auto& x: threads) x.join();
return 0; }
std::unique_lock::owns_lock
bool owns_lock()noexcept;
如果当前unique_lock管理的muex,被当前的unique_lock上锁了那么返回true,其他返回false.
#include <iostream> // std::cout #include <vector> // std::vector #include <thread> // std::thread #include <mutex> // std::mutex, std::unique_lock, std::try_to_lock
std::mutex mtx; // mutex for critical section
void print_star () { std::unique_lock<std::mutex> lck(mtx,std::try_to_lock); // print '*' if successfully locked, 'x' otherwise: if (lck.owns_lock()) std::cout << '*'; else std::cout << 'x'; }
int main () { std::vector<std::thread> threads; for (int i=0; i<500; ++i) threads.emplace_back(print_star);
for (auto& x: threads) x.join();
return 0; }
std::unique_lock::operator bool()
explicit operator bool()noexcept;
如果当前unique_lock管理的mutex对象被上锁了,返回true,否则返回false.
#include <iostream> // std::cout #include <vector> // std::vector #include <thread> // std::thread #include <mutex> // std::mutex, std::unique_lock, std::try_to_lock
std::mutex mtx; // mutex for critical section
void print_star () { std::unique_lock<std::mutex> lck(mtx,std::try_to_lock); // print '*' if successfully locked, 'x' otherwise: if (lck) std::cout << '*'; else std::cout << 'x'; }
int main () { std::vector<std::thread> threads; for (int i=0; i<500; ++i) threads.emplace_back(print_star);
for (auto& x: threads) x.join();
return 0; }
std::unique_lock::mutex
mutex_type* mutex()noexcept;
返回一个指针指向当前unique_lock管理的mutex对象。
但是unique_lock仍然拥有mutex的所有权,当unique_lock析构的时候mutex对象被解锁.
补充:
lock_guard (mutex_type& m, adopt_lock_t tag);
在lock_gurad的构造函数中,可以接受一个标签:
std::adpot_lock
该标签意味着当前线程中的互斥量(mutex),已经被当前线程上过锁了,现在lock_guard来接手管理.
unique_lock (mutex_type& m, try_to_lock_t tag);
unique_lock (mutex_type& m, defer_lock_t tag) noexcept;
unique_lock (mutex_type& m, adopt_lock_t tag);
在unique_lock的构造函数中,可以接受三个标签:
std::try_to_lock //调用所管理的muetx的try_lock函数给当前线程内的管理的当前mutex上锁.
std::defer_lock//延迟上锁,虽然接手了mutex但是并没有给它上锁.需要后续的上锁操作.
std::adopt_lock//当前线程已经对mutex上锁过了,现在unique_lock来接手管理。