C++多线程网课学习(13-07)

C++多线程网课学习(13-07),第1张

C++多线程网课学习(13-07) 1.设计模式概述

【概念】代码的一些写法:程序灵活,维护方便;但代码晦涩,不易于别人接手。 2. 单例设计模式


【概念】:整个项目中,有某个或某些特殊的类,属于该类的对象,只能被创建1个。 3. 单例设计模式共享数据分析及解决


!!!单例模式的具体内容还应该参考 该链接,这里讲的更加详细和准确。本文的作者只讲解了双重锁定,而实际上该方法也已经被弃用,由于某些不安全因素,因此该链接中给出了更加合理的方法。 3.1 建议

建议在多线程中,将单例类在主线程中提前定义并初始化相关静态变量。如果对单例类中变量只读,则只读的共享数据不需要加锁。如果:需要在子线程中创建单例类对象,这种线程且不止一个,则会出现撞上初始化被多次执行。解决方法:增加互斥量

//.cpp
//类的私有静态变量外部可以直接调用??
std::mu_tex my_tex;

//线程入口函数
void my_thread(){
    A* my_a=A::getInstance();
    //...
}
class A{
public:
    static A * getInstance(){
    
    if (my_instance==NULL){//方法二,双重锁定
        unique_lock thread_mutex(my_tex);//方法一,效率低,解决不同线程撞上同样初始化
        if(my_instance==nullptr){
            my_instance=new A();
            static My_garbage gb;//调用该类的析构函数时,顺势把new的my_instance删除掉。
        }     
    }
    return my_instance;
    }
private:
    static A *my_instance;
    A();//!私有化构造函数,即全局只能有一个该类。
    ~A();
};

class My_garbage{
//!!!巧妙设计,可以delete掉未知的new 变量。
    public:
        My_garbage(){};
        ~My_garbage(){
            if(A::my_instance){
                delete A::my_instance;
                A::my_instance=nullptr;
            }
        }
};

//*******************.h
//类静态变量初始化
A *A::my_instance==nullptr;

A::A(){}
A::~A(){}
A::test(){
    cout<<"test"< 
4. call_once() 函数模板 

c++引入的函数,该函数第二个参数是一个函数某名a();

!!!call_once()功能能够保证函数a()只被调用一次。不管有若干个线程调用该函数。

call_once具备互斥量这种能力,且效率上,比互斥量消耗的资源更少。

需要与标记结合使用,标记为 std::once_flag; 其实once_flag为一个结构。

call_once就是通过这个标记来决定对应的函数a()是否执行,调用call_once成功后,call_once就把标记设置为已调用状态,后续再次调用,那么对应的函数a()就不会再被执行了。

利用call_once来实现单例模式

std::once_flag my_flag;//系统定义的标记
//...
class A{
private:
    static A* my_instance;
    A(){}
public:
static void creatInstance(){
    //该函数只被调用一次
    my_instance=new A();
    static my_garbage my_g;
}
static A* getInstance(){
    //该方法,每次都要通过call_once判断my_instance是否已经被定义。
    call_once(my_flag,creatInstance());
    return my_instance;
}
};
四、补充 静态变量与局部变量区别

(1)所有全局变量都是静态变量;而局部变量只有定义时加上类型修饰符static,才为局部静态变量。(2)静态变量不是说其值保持不变,其拥有的是值是可变的。说其静态,是因为其不会随着函数
调用和退出而发生变化,即上次调用函数的时候,如果我们给静态变量赋予某个值,下次函数调用的时,
这个值保持不变。(3)静态局部变量与auto自动变量的区别

3.1 两者均是只能在函数内部使用,出了函数不能再使用;但是auto自动变量会随着函数退出而消失,static局部变量会一直存在,但在函数外部不能使用,
只能再次调用该函数时,它保留上次调用时的值,并可以继续使用。3.2 static变量初始化语句只需在第一次调用时使用;auto变量每次函数调用都会重新初始化。3.3 static变量初始化必须是常量或常量表达式,如果定义时没有赋值,系统会自动赋初值0(数值型变量为0,字符型为字符变量);
auto变量不赋初值,其值将会是一个不确定的值。3.4 当多次调用一个函数且要求在调用之间保持某些变量的值时,考虑采用静态局部变量。
虽然全局变量也可达到上述目的,但全局变量会造成意外的副作用,建议还是局部静态变量。3.5 局部静态变量占用内存时间较长,可读性差,非必要,避免使用。

全局变量与局部变量的区别

(1)作用域不同:全局变量作用域为整个程序;局部变量作用域为当前函数或者循环。(2)内存存储方式不同:全局变量存储在全局数据区中,局部变量存储在栈区。(3)生命周期不同:全局变量的生命期和主程序一样,随程序的销毁而销毁;局部变量在函数内部或
循环内部,随函数退出或循环退出而销毁。(4)使用方式不同:全局变量声明后程序的各个部分都可以用到,但是局部变量只能局部使用,
函数内部会优先使用局部变量再使用全局变量。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5718301.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存