std::condition_variable
notify_one()
wait()
class A{
public:
std::unique_lock<std::mutex> my_move(){
std::unique_lock<std::mutex> tem(my_mutex1);
return tem;
}
void inmRQ(){
for(int i=1;i<=100000000;i++){
cout<<"start"<<endl;
std::unique_lock<std::mutex> myguard(my_mutex1);
mRQ.push(i);
my_cond.notify_one();//我们把wait()的线程唤醒,执行完这行,那么outmRQ()里的wait就会被唤醒(只能唤醒一个线程)
}
}
void outmRQ(){
int command=0;
while (true){
std::unique_lock<std::mutex> mygurad(my_mutex1);
//wait()用来等一个东西
//如果第二个参数lambda表达式返回值是flase,那么wait()将解锁互斥量,并堵塞到本行
//如果为true , 那么wait()直接返回
//堵塞到其他线程调用notify_one()成员函数为止
//如果写成my_cond.wait(mygurad)那么就和第二个参数返回flase一样
//当其他线程调用了notify_one()将本wait唤醒后
//a)如果wait不断尝试获取互斥锁,直到获取成功
//b)如果有第二个参数,就执行判断,如果为true就向下执行,如果为flase就又解锁则塞
//b)如果没有第二个参数,这直接向下执行
my_cond.wait(mygurad ,[this]{
if( !mRQ.empty() )
return true;
return false;
});
command=mRQ.front();
mRQ.pop();//操作共享数据
mygurad.unlock();
cout<<command<<endl;
//其他操作
}
}
private:
std::queue<int> mRQ;
std::mutex my_mutex1;
std::condition_variable my_cond;//生成一个条件变量对象
};
notify_all()
尝试把该
condition_variable
对象的wait
线程全都唤醒
单例设计模式
单例 , 在整个项目中 , 有属于某个或者某些特殊的类 , 属于该类的对象 , 我只能创建一个 , 多了创建不了
class A{
private:
A(){} //私有化构造函数
static A *mya;//静态成员函数
public:
static A* GetInstance(){
if( mya==NULL ){
mya = new A();
}
return mya;
}
void test(){
cout<<"测试"<<endl;
}
};
A* A::mya = NULL;
int main(){
A *p_a = A::GetInstance();//创建一个对象 , 返回该类对象指针
A *p_b = A::GetInstance();
return 0;
}
单例技巧
class A{
private:
A(){} //私有化构造函数
static A *mya;//静态成员函数
public:
static A* GetInstance(){
if( mya==NULL ){
mya = new A();
static CGhuishou c;
}
return mya;
}
class CGhuishou{//类中套类 , 用来释放对象
public:
~CGhuishou(){
if( A::mya ){
delete A::mya;
A::mya = NULL;
}
}
};
void test(){
cout<<"test"<<endl;
}
};
A* A::mya = NULL;
int main(){
A *p_a = A::GetInstance();//创建一个对象 , 返回该类对象指针
A *p_b = A::GetInstance();
p_a->test();
return 0;
}
单例设计模式共享数据问题
建议在主线程初始化单例对象
当在线程中初始化单例时 , 就要注意数据共享问题
using namespace std;
std::mutex mymutex;
class A{
private:
A(){} //私有化构造函数
static A *mya;//静态成员函数
public:
static A* GetInstance(){//这里可能会出现reorder问题,请自行百度
if( mya==NULL ){//双重锁定(双重检查)
mymutex.lock();
if( mya==NULL ){
mya = new A();
static CGhuishou c;
}
mymutex.unlock();
}
return mya;
}
class CGhuishou{//类中套类 , 用来释放对象
public:
~CGhuishou(){
if( A::mya ){
delete A::mya;
A::mya = NULL;
}
}
};
void test(){
cout<<"test"<<endl;
}
};
A* A::mya = NULL;
void run1(){
while (true){
A* ptr=A::GetInstance();
cout<<"run1"<<endl;
}
}
void run2(){
while (true){
A* ptr=A::GetInstance();
cout<<"run2"<<endl;
}
}
int main(){
std::thread myjob1(ref(run1));
std::thread myjob2(ref(run2));
myjob1.join();
myjob2.join();
return 0;
}
std::call_one()
第二个参数是一个函数名
a( )
功能 :
call_one
功能是保证函数a()
只被调用一次具备互斥量能力 , 比互斥量消耗少一点
call_one()
需要与一个标记结合使用 , 这个标记std::once_flag
(结构体)
call_one()
通过这个标记来决定对应的函数a()
是否执行 , 调用call_one()
标记std::once_flag
以后a()
就不会再执行了
std::mutex mymutex;
std::once_flag flag;
class A{
private:
A(){} //私有化构造函数
static A *mya;//静态成员函数
public:
static void GreatInstance(){//只被调用一次
cout<<"I was called"<<endl;
mya = new A();
static CGhuishou c;
}
static A* GetInstance(){
std::call_once(flag,GreatInstance);
return mya;
}
class CGhuishou{//类中套类 , 用来释放对象
public:
~CGhuishou(){
if( A::mya ){
delete A::mya;
A::mya = NULL;
}
}
};
void test(){
cout<<"test"<<endl;
}
};
A* A::mya = NULL;
void run1(){
while (true){
A* ptr=A::GetInstance();
cout<<"run1"<<endl;
}
}
void run2(){
while (true){
A* ptr=A::GetInstance();
cout<<"run2"<<endl;
}
}