mutex系列类(四种)
lock 类(两种)
其他类型
函数
基本的 std::mutex
是 C++11 中最基本的互斥量,std::mutex
对象提供了独占所有权的特性——即不支持递归地对 std::mutex
对象上锁。而 std::recursive_lock
则可以递归地对互斥量对象上锁。
std::mutex 的成员函数:
lock()
:调用线程将锁住该互斥量。线程调用该函数会发生下面3种情况:
unlock()
:释放对互斥量的所有权。try_lock()
:尝试锁住互斥量,如果互斥量被其他线程占有,则当前线程也不会被阻塞。线程调用该函数也会出现下面3种情况:
mutex
的lock和unlock#include
#include
#include
#include
std::mutex g_mutex;
int g_count = 0;
void counter(){
for(int i = 0; i < 100000; i++){
g_mutex.lock();
g_count++;
// 前面代码如有异常,unlock 就调不到了。
g_mutex.unlock();
}
}
int main()
{
std::thread threads[4];
for(int i = 0; i < 4; i++){
threads[i] = std::thread(counter);
}
for (auto& th : threads){
th.join();
}
std::cout << g_count << std::endl;
return 0;
}
boost
简化操作创建一组线程的操作:前置准备
#include<stdio.h>
#include <mutex>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
std::mutex g_mutex;
int g_count = 0;
void counter(){
for(int i = 0; i < 100000; i++){
g_mutex.lock();
g_count++;
// 前面代码如有异常,unlock 就调不到了。
g_mutex.unlock();
}
}
int main()
{
boost::thread_group threadGroup;
for(int i = 0; i < 4; i++){
threadGroup.create_thread(&counter);
}
threadGroup.join_all();
std::cout << g_count << std::endl;
return 0;
}
lock()
是阻塞式的,如果没有获取到锁,就会一直阻塞到这一句。直到当前锁被释放,然后才会唤醒当前线程,尝试区获取锁。#include
#include
#include
#include
std::mutex mutex;
volatile int counter = 0;
void run() {
std::cout << "wait for mutex.lock 【死等】\n" << std::endl;
mutex.lock();
std::cout << "成功获取到了锁 【死等】\n" << std::endl;
++counter;
mutex.unlock();
}
int main()
{
mutex.lock();
std::thread varname(run);
varname.join();
mutex.unlock();
std::cout << "counter should 100000, but counter = " << counter << "\n";
return 0;
}
try_lock
:#include<stdio.h>
#include <mutex>
#include <iostream>
#include <thread>
volatile int counter = 0; // volatile 避免编译器优化 每次都去内存里去读
void run(std::mutex &mutex) {
for (int i = 0; i<10000; ++i)
{
if (mutex.try_lock())
{
++counter;
mutex.unlock();
}
}
}
int main()
{
std::mutex mutex;
std::thread threads[10];
for (int i = 0; i<10; ++i){
threads[i] = std::thread(run, std::ref(mutex));
}
for (auto& th : threads){
th.join();
}
std::cout << "counter should 100000, but counter = " << counter << "\n";
return 0;
}
// 由于try_lock
没有获取到锁就会直接返回一个false,从而导致有一个counter没有自增,而我们不知道什么时候会失败,所以结果是不可预期的。这是线程不安全的
std::time_mutex
比 std::mutex
多了两个成员函数,try_lock_for(),try_lock_until()
。
try_lock_for
:
try_lock_until
::
/* 作用:在参数时间内阻塞尝试获取锁
* 参数:一个 chrono::duration 对象,指定此方法尝试获取 mutex 所有权的最大时间量。
* 返回值:如果此方法成功获取 mutex 的所有权,则为 true;否则为 false。
* 备注:如果调用线程已拥有 mutex,则该行为不确定
*/
template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& Rel_time);
/* 作用:在参数时间到达之前阻塞尝试获取锁
* 参数:一个时间点,指定阈值,在此之后此方法不再尝试获取 mutex 所有权。
* 返回值:如果此方法成功获取 mutex 的所有权,则为 true;否则为 false。
* 备注:如果调用线程已拥有 mutex,则该行为不确定
*/
template<class Clock, class Duration>
bool try_lock_for(const chrono::time_point<Clock, Duration>& Abs_time);
bool try_lock_until(const xtime *Abs_time);
canjian
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
void run500ms(std::timed_mutex &mutex) {
std::cout << "wait for mutex.lock [阻塞,直到超时/获取到锁])\n" << std::endl;
auto _500ms = std::chrono::minutes (10);
if (mutex.try_lock_for(_500ms)) {
std::cout << "获得了锁" << std::endl;
} else {
std::cout << "超时, 未获得锁\n" << std::endl;
}
}
int main() {
std::timed_mutex mutex;
mutex.lock();
std::thread thread(run500ms, std::ref(mutex));
thread.join();
mutex.unlock();
// getchar();
return 0;
}
#include
#include
#include
#include
#include
std::mutex cout_mutex; // control access to std::cout
std::timed_mutex mutex;
void job(int id)
{
using Ms = std::chrono::minutes ;
std::ostringstream stream;
for (int i = 0; i < 3; ++i) {
if (mutex.try_lock_for(Ms(100))) {
stream << "success ";
std::this_thread::sleep_for(Ms(100));
mutex.unlock();
} else {
stream << "failed ";
}
// std::this_thread::sleep_for(Ms(100));
}
std::lock_guard<std::mutex> lock(cout_mutex);
std::cout << "[" << id << "] " << stream.str() << "\n";
}
int main()
{
std::vector<std::thread> threads;
threads.reserve(4);
for (int i = 0; i < 4; ++i) {
threads.emplace_back(job, i);
}
for (auto& i: threads) {
i.join();
}
}
#include
#include
#include
#include
void run500ms(std::timed_mutex &mutex) {
std::cout << "wait for mutex.lock [阻塞,直到超时/获取到锁])\n" << std::endl;
auto _500ms = std::chrono::minutes (10);
if (mutex.try_lock_until(std::chrono::system_clock::now() + _500ms)) {
std::cout << "获得了锁" << std::endl;
} else {
std::cout << "超时, 未获得锁\n" << std::endl;
}
}
int main() {
std::timed_mutex mutex;
mutex.lock();
std::thread thread(run500ms, std::ref(mutex));
thread.join();
mutex.unlock();
// getchar();
return 0;
}
#include
#include
#include
#include
volatile int counter = 0; // volatile 避免编译器优化 每次都去内存里去读
void run(std::mutex &mutex) {
for (int i = 0; i<10000; ++i)
{
std::lock_guard<std::mutex> lock(mutex); // 加锁
++counter;
} // 离开当前作用域,自动解锁
}
int main()
{
std::mutex mutex;
std::thread threads[10];
for (int i = 0; i<10; ++i){
threads[i] = std::thread(run, std::ref(mutex));
}
for (auto& th : threads){
th.join();
}
std::cout << "counter should 100000, but counter = " << counter << "\n";
return 0;
}
#include
#include
#include
#include
boost::mutex mutex;
volatile int counter = 0; // volatile 避免编译器优化 每次都去内存里去读
void run() {
for (int i = 0; i<10000; ++i)
{
boost::lock_guard<boost::mutex> lock(mutex);
++counter;
}
}
int main()
{
boost::thread_group threads;
for (int i = 0; i < 10; ++i) {
threads.create_thread(&run);
}
threads.join_all();
std::cout << "counter should 100000, but counter = " << counter << "\n";
return 0;
}
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <deque>
#include <condition_variable>
std::deque<int> global_deque;
std::mutex global_mutex;
std::condition_variable global_ConditionVar;
// 生产者线程
void Producer()
{
while (true)
{
// 休眠5毫秒
std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::unique_lock<std::mutex> lock(global_mutex);
global_deque.push_front(1);
std::cout << "生产者生产了数据" << std::endl;
global_ConditionVar.notify_all();
}
}
// 消费者线程
void Consumer()
{
while (true)
{
std::unique_lock<std::mutex> lock(global_mutex);
// 当队列为空时返回false,则一直阻塞在这一行
global_ConditionVar.wait(lock, [] {
return !global_deque.empty(); });
global_deque.pop_back();
std::cout << "消费者消费了数据" << std::endl;
global_ConditionVar.notify_all();
}
}
int main()
{
std::thread consumer_Thread(Consumer);
//std::thread consumer_Thread1(Consumer);
std::thread producer_Thread(Producer);
consumer_Thread.join();
//consumer_Thread1.join();
producer_Thread.join();
getchar();
return 0;
}
C++ 11互斥锁的应用(针对于多线程的情况)
C++ 多线程 (4) 互斥量(mutex)与锁(lock)
C++11多线程——lock详解