/* *lock_guard C++源码 内容也比较简单 *私有化了拷贝构造和赋值拷贝 *在内部对锁和构造和析构进行了适配 */ template<class _Mutex> class lock_guard<_Mutex> { // specialization for a single mutex public: typedef _Mutex mutex_type; explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock _MyMutex.lock(); } lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) { // construct but don't lock } ~lock_guard() _NOEXCEPT { // unlock _MyMutex.unlock(); } lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete; private: _Mutex& _MyMutex; };
#include <thread> #include <mutex> #include <vector> #include <iostream> #include <algorithm> #include <chrono> std::mutex my_lock; void add(int &num, int &sum){ std::cout <<"in thread " << std::this_thread::get_id() << std::endl; while(true){ auto beginTime = std::chrono::high_resolution_clock::now(); std::lock_guard<std::mutex> lock(my_lock); auto endTime = std::chrono::high_resolution_clock::now(); auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout <<std::this_thread::get_id() << " elapsed time is " << elapsedTime.count() << " second" << std::endl; if (num < 10){ //运行条件 num += 1; sum += num; } else { //退出条件 break; } } } int main(){ int sum = 0; int num = 0; std::vector<std::thread> ver; //保存线程的vector for(int i = 0; i < 2; ++i){ std::thread t = std::thread(add, std::ref(num), std::ref(sum)); ver.emplace_back(std::move(t)); //保存线程 } std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join std::cout << sum << std::endl; }
root@ubuntu:~/c++# g++ -std=c++11 lock_guard1.cpp -o thread1 -pthread
root@ubuntu:~/c++# ./thread1 in thread in thread 281472855114192281472863506896 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472863506896 elapsed time is 0 second 281472855114192 elapsed time is 11 second 55
281472855114192这个线程花了11秒才获得锁
我们会尝试用mutex的lock()去锁定这个mutex,但如果没有锁定成功,我也会立即返回,并不会阻塞在那里;
用这个try_to_lock的前提是你自己不能先lock。实例代码如下:
#include <thread> #include <mutex> #include <vector> #include <iostream> #include <algorithm> #include <chrono> std::mutex my_lock; void add(int &num, int &sum){ std::cout <<"in thread " << std::this_thread::get_id() << std::endl; while(true){ auto beginTime = std::chrono::high_resolution_clock::now(); //std::lock_guard<std::mutex> lock(my_lock); std::unique_lock<std::mutex> sbguard(my_lock, std::try_to_lock); auto endTime = std::chrono::high_resolution_clock::now(); auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout <<std::this_thread::get_id() << " elapsed time is " << elapsedTime.count() << " second" << std::endl; if (sbguard.owns_lock()) { if (num < 10){ //运行条件 num += 1; sum += num; } else { //退出条件 break; } } else { std::cout << std::this_thread::get_id() << " do other " << std::endl; } } } int main(){ int sum = 0; int num = 0; std::vector<std::thread> ver; //保存线程的vector for(int i = 0; i < 2; ++i){ std::thread t = std::thread(add, std::ref(num), std::ref(sum)); ver.emplace_back(std::move(t)); //保存线程 } std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join std::cout << sum << std::endl; }
root@ubuntu:~/c++# g++ -std=c++11 lock_guard1.cpp -o thread1 -pthread root@ubuntu:~/c++# ./thread1 in thread in thread 281473401266640281473409659344 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473409659344 elapsed time is 0 second 281473401266640 elapsed time is 0 second 281473401266640 do other 281473401266640 elapsed time is 0 second 55
std::defer_lock
这个参数表示暂时先不lock,之后手动去lock,但是使用之前也是不允许去lock。一般用来搭配unique_lock的成员函数去使用。下面就列举defer_lock和一些unique_lock成员函数的使用方法。
当使用了defer_lock参数时,在创建了unique_lock的对象时就不会自动加锁,那么就需要借助lock这个成员函数来进行手动加锁,当然也有unlock来手动解锁。这个和mutex的lock和unlock使用方法一样,实现代码如下:
#include <thread> #include <mutex> #include <vector> #include <iostream> #include <algorithm> #include <chrono> std::mutex my_lock; void add(int &num, int &sum){ std::cout <<"in thread " << std::this_thread::get_id() << std::endl; while(true){ std::unique_lock<std::mutex> sbguard(my_lock, std::defer_lock); auto beginTime = std::chrono::high_resolution_clock::now(); sbguard.lock(); num += 1; sbguard.unlock(); auto endTime = std::chrono::high_resolution_clock::now(); auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime); std::cout <<std::this_thread::get_id() << " elapsed time is " << elapsedTime.count() << " second" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(100)); if(num >= 10) { break; } } } int main(){ int sum = 0; int num = 0; std::vector<std::thread> ver; //保存线程的vector for(int i = 0; i < 2; ++i){ std::thread t = std::thread(add, std::ref(num), std::ref(sum)); ver.emplace_back(std::move(t)); //保存线程 } std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join std::cout << sum << std::endl; }
root@ubuntu:~/c++# ./thread1 in thread in thread 281473381425616281473373032912 281473373032912 elapsed time is 281473381425616 elapsed time is 00 second second 281473373032912 elapsed time is 0 second 281473381425616 elapsed time is 0 second 281473373032912 elapsed time is 0 second 281473381425616 elapsed time is 0 second 281473373032912 elapsed time is 0 second 281473381425616 elapsed time is 0 second 281473373032912 elapsed time is 0 second 281473381425616 elapsed time is 0 second 0
root@ubuntu:~/c++# cat lock_guard1.cpp #include <thread> #include <mutex> #include <vector> #include <iostream> #include <algorithm> #include <chrono> std::mutex my_lock; void add(int &num, int &sum){ std::cout <<"in thread " << std::this_thread::get_id() << std::endl; while(true){ std::unique_lock<std::mutex> sbguard(my_lock, std::defer_lock); auto beginTime = std::chrono::high_resolution_clock::now(); sbguard.lock(); auto endTime = std::chrono::high_resolution_clock::now(); auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime); std::cout <<std::this_thread::get_id() << " elapsed time is " << elapsedTime.count() << " second" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(2000)); num += 1; sbguard.unlock(); //std::this_thread::sleep_for(std::chrono::milliseconds(100)); if(num >= 10) { break; } } } int main(){ int sum = 0; int num = 0; std::vector<std::thread> ver; //保存线程的vector for(int i = 0; i < 2; ++i){ std::thread t = std::thread(add, std::ref(num), std::ref(sum)); ver.emplace_back(std::move(t)); //保存线程 } std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join std::cout << sum << std::endl; }
root@ubuntu:~/c++# g++ -std=c++11 lock_guard1.cpp -o thread1 -pthread root@ubuntu:~/c++# ./thread1 in thread in thread 281473229185488281473237578192 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473229185488 elapsed time is 0 second 281473237578192 elapsed time is 20 second 0
281473237578192 等了 20 second