admin管理员组文章数量:1599531
lock、unlock
lock()和unlock()函数必须同时成对存在,不存在一多一少的情况;
lock()调用线程将锁住该互斥量;
- 若该互斥量当前没有被锁住,则进行加锁;
- 若当前互斥量被其他线程锁住,则当前的调用线程被阻塞;
- 若当前互斥量被当前调用的线程锁住,则会产生死锁,因为同一个线程不允许锁两次;
unlock()进行解锁操作,释放互斥量的所有权;
#include <iostream>
#include <thread>
#include <mutex>
#include <deque>
class lock_unlock{
public:
lock_unlock(){}
void WriteOperate(){
for(int i=0;i<1000;i++){
nums_mutex.lock();
std::cout<<"写入一个元素"<<std::endl;
nums_deque.push_back(i);
nums_mutex.unlock();
}
}
void ReadOperate(){
for(int i=0;i<1000;i++){
nums_mutex.lock();
if(!nums_deque.empty()){
std::cout<<"读出第一个元素"<<nums_deque.front()<<std::endl;
nums_deque.pop_front();
}
nums_mutex.unlock();
}
}
private:
std::deque<int> nums_deque;
std::mutex nums_mutex;
};
int main(int argc,char* argv[]){
lock_unlock lock;
std::thread nums_thread1(&lock_unlock::WriteOperate,std::ref(lock));
std::thread nums_thread2(&lock_unlock::ReadOperate,std::ref(lock));
/*线程阻塞*/
nums_thread1.join();
nums_thread2.join();
std::cout<<"执行完毕!"<<std::endl;
return 0;
}
lock_guard
/*lock_guard()是一个类模板,里面已经存在lock()和unlock()函数,因此只需要一个即可*/
#include <iostream>
#include <thread>
#include <mutex>
#include <deque>
class lock_guard{
public:
void WriteOperate(){
for(auto i=0;i<1000;i+=2){
std::lock_guard<std::mutex> nums_lockguard(nums_mutex);
nums_deque.push_back(i);
}
}
void ReadOpreate(){
for(auto i=0;i<1000;i++){
std::lock_guard<std::mutex> nums_lockguard(nums_mutex);
if(!nums_deque.empty()){
std::cout<<nums_deque.front()<<std::endl;
nums_deque.pop_front();
}
}
}
private:
std::deque<int> nums_deque;
std::mutex nums_mutex;
};
int main(int argc,char*[]){
lock_guard guard;
std::thread nums_thread1(&lock_guard::WriteOperate,std::ref(guard));
std::thread nums_thread2(&lock_guard::ReadOpreate,std::ref(guard));
/*线程阻塞*/
nums_thread1.join();
nums_thread2.join();
std::cout<<"执行完毕!"<<std::endl;
return 0;
}
condition_variable
condition_variable(条件变量),通俗的将线程根据条件去拿锁,若不符合条件则休眠,直到有线程唤醒它才会继续去竞争锁,用于线程同步,只能配合unique_lock使用,前面3个wait函数需要传入一个已经上锁的变量unique_lock<mutex>,此外第二个参数传入lambda表达式用于防止虚假唤醒;而condition_variable_any可以应用于任意的lock;
- wait:阻塞自己,等待唤醒;wait函数存在两个参数,第一个是unique_lock,第二个参数是lambda表达式或其他函数,返回值是bool,若第二个参数不传入,默认条件判断为false,相当于互斥锁,即每次都需要notify唤醒,如果所有唤醒线程结束运行,而没有线程唤醒它则休眠堵塞;
- wait_for:阻塞自己,等待唤醒,最多等待一段时间;
- wait_unti:阻塞自己,等待唤醒,最多等待到某个时刻;
- notify_one:唤醒一个等待在这个条件变量上的线程,若线程没有进入休眠状态则无效;
- notify_all:唤醒所有等待在这个条件变量上的线程;
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <list>
class condition_variables{
public:
void WriteOperate(){
for(auto i=0;i<100;i+=2){
std::unique_lock<std::mutex> mg_lock(mg_mutex);
message.push_back(i);
mg_condv.notify_one();/*唤醒线程*/
}
}
void ReadOperate(){
for(auto i=0;i<100;i+=2){
std::unique_lock<std::mutex> mg_lock(mg_mutex);
/*lambda表达式无参数传入可以省略,this类指针,值传递,返回值bool型,自动匹配类型可省略*/
mg_condv.wait(mg_lock,[this]{return !message.empty();});
std::cout<<message.front()<<std::endl;
message.pop_front();
}
}
private:
std::list<int> message;
std::mutex mg_mutex;
std::condition_variable mg_condv;
};
int main(int argc,char* argv[]){
condition_variables cond;
std::thread W_thread(&condition_variables::WriteOperate,&cond);
std::thread R_thread(&condition_variables::ReadOperate,&cond);
W_thread.join();
R_thread.join();
return 0;
}
本文标签: unlockLockconditionvariablelockguard
版权声明:本文标题:C++lock、unlock、lock_guard和condition_variable锁 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728323469a1154131.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论