C++如何解决单例懒汉式和多线程问题

技术C++如何解决单例懒汉式和多线程问题这篇文章主要为大家展示了“C++如何解决单例懒汉式和多线程问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C++如何解决单例懒汉式和

本文主要给大家展示“C如何解决单懒多线程问题”,简单易懂,条理清晰,希望能帮你解决疑惑。让边肖带领大家学习学习《C如何解决单懒多线程问题》一文。

单一惰性和多线程问题

作为单例模式,在整个程序运行过程中,将只构建一个内存空间,以实现这一目标。

1.构造函数需要设置为私有成员。

2.需要一个私有静态指针来指向自身。

3.需要一个公共静态函数来公开上面的静态指针。

下面的代码是一个懒鬼的例子。

单击此处折叠或打开。

#包括牡蛎

使用命名空间标准;

类single_ins

{

私人:

int a;

int b;

single_ins()

{

a=0;

b=0;

}

静态single _ ins * myc

公众号:

void setval(const int a,const int b)

{

this-a=a;

this-b=b;

}

无效打印()

{

cout 'a: ' aendl

cout 'b: ' bendl

}

静态single_ins* setp()

{

//?

if(myc==NULL)

{

nbsp;          myc = new single_ins;

  •         }

  •         //?

  •         return myc;

  •     }

  •     static void  pfree()

  •     {

  •         if(myc != NULL)

  •         {

  •             delete myc;

  •             myc = NULL;

  •         }

  •     }

  • };

  • //? init static value

  • single_ins* single_ins::myc = NULL;

  • //nit static value

  • //single_ins* single_ins::myc = new single_ins;

  • int main()

  • {

  •     single_ins* a = single_ins::setp();

  •     single_ins* b = single_ins::setp();

  •     a->setval(10,20);

  •     b->print();

  •     cout<<a<<" "<<b<<endl;

  •     single_ins::pfree();

  • }

  • 但是上面的代码有明显的问题,就是遇到多线程的情况下,因为多个线程如果同事创建内存,由于彼此之间
    并不能及时检查到内存已经分配,会分配多个内存,这个时候我们至少需要一个线程间同步手段来让他们之间
    串行的执行,这个时候就涉及到两次检查(double check)
    如果没有mutex保护就是下面这个程序:

    点击(此处)折叠或打开

    1. #include <iostream>

    2. #include <unistd.h>

    3. using namespace std;

    4. //单列模式

    5. class single_ins

    6. {

    7.         private:

    8.                 int a;

    9.                 int b;

    10.                 single_ins()

    11.                 {

    12.                         cout<<"con begin\n";

    13.                         a= 0;

    14.                         b= 0;

    15.                         sleep(10); //故意拖长构造函数执行时间,造成懒汉式多线程问题

    16.                         cout<<"con end\n";

    17.                 }

    18.                 static single_ins* myc;//单例需要一个静态指针

    19.                 static int cnt;//构造调用次数统计

    20.         public:

    21.                 void setval(const int& a,const int& b)

    22.                 {

    23.                         this->a = a;

    24.                         this->b = b;

    25.                 }

    26.                 void print()

    27.                 {

    28.                         cout<<"a:"<<a<<endl;

    29.                         cout<<"b:"<<b<<endl;

    30.                         cout<<cnt<<endl;

    31.                 }

    32.                 static single_ins* setp() //函数获得指针值赋给静态成员指针变量

    33.                 {

    34.                         //懒汉式

    35.                         if(myc == NULL)

    36.                         {

    37.                                 myc = new single_ins;

    38.                                 cnt++;

    39.                         }

    40.                         //懒汉式

    41.                         return myc;

    42.                 }

    43.                 static void  pfree()

    44.                 {

    45.                         if(myc != NULL)

    46.                         {

    47.                                 delete myc;

    48.                                 myc = NULL;

    49.                         }

    50.                 }

    51. };

    52. //懒汉式 init static value

    53. single_ins* single_ins::myc = NULL;

    54. int single_ins::cnt = 0;

    55. //饿汉试 init static value

    56. //single_ins* single_ins::myc = new single_ins;

    57. /*

    58.    懒汉式的问题在于多线程调用的时候会出现问题,很可能同时建立出多个内存空间,

    59.    而不是单列了。

    60.    */

    61. void* main21(void* argc)

    62. {

    63.         single_ins* inp = (single_ins*)argc;

    64.         inp = single_ins::setp();

    65.         inp->setval(10,20);

    66.         inp->print();

    67.         cout<<inp<<"\n";

    68.         return NULL;

    69. }

    70. int main(void)

    71. {

    72.         pthread_t tid;

    73.         single_ins* a[3] = {NULL};

    74.         void* tret[3] = {NULL};

    75.         for(int i = 0 ; i<3; i++)

    76.         {

    77.                 pthread_create(&tid,NULL,main21,(void*)a[i]);

    78.                 //pthread_join(tid, &(tret[i]));

    79.         }

    80.         sleep(50);

    81.         single_ins::pfree();

    82. }

    会跑出结果
    con begin
    con begin
    con begin
    con end
    a:10
    b:20
    1
    0x7fc3880008c0
    con end
    a:10
    b:20
    2
    0x7fc3800008c0
    con end
    a:10
    b:20
    3
    0x7fc3840008c0

    可以看到
    0x7fc3880008c0 0x7fc3800008c0 0x7fc3840008c0
    明显是3个不同的内存空间 这就不对了,而且可以看到构造函数
    调用了3次
    为此我们使用mutex来保护临时

    如下:
     static single_ins* setp() //函数获得指针值赋给静态成员指针变量
     39         {
     40             //懒汉式
     41             if(myc == NULL)
     42             {
     43                 pthread_mutex_lock(&counter_mutex); //mutex 保护临界区
     44                 if(myc == NULL) //两次检查
     45                 {
     46                     myc = new single_ins;                                                                                                                           
     47                     cnt++;
     48                 }
     49                 pthread_mutex_unlock(&counter_mutex); //mutex结束
     50             }

    这样代码如下:

    点击(此处)折叠或打开

    1. #include <iostream>

    2. #include <unistd.h>

    3. using namespace std;

    4. pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

    5. //单列模式

    6. class single_ins

    7. {

    8.         private:

    9.                 int a;

    10.                 int b;

    11.                 single_ins()

    12.                 {

    13.                         cout<<"con begin\n";

    14.                         a= 0;

    15.                         b= 0;

    16.                         sleep(10); //故意拖长构造函数执行时间,造成懒汉式多线程问题

    17.                         cout<<"con end\n";

    18.                 }

    19.                 static single_ins* myc;//单例需要一个静态指针

    20.                 static int cnt;//构造调用次数统计

    21.         public:

    22.                 void setval(const int& a,const int& b)

    23.                 {

    24.                         this->a = a;

    25.                         this->b = b;

    26.                 }

    27.                 void print()

    28.                 {

    29.                         cout<<"a:"<<a<<endl;

    30.                         cout<<"b:"<<b<<endl;

    31.                         cout<<cnt<<endl;

    32.                 }

    33.                 static single_ins* setp() //函数获得指针值赋给静态成员指针变量

    34.                 {

    35.                         //懒汉式

    36.                         if(myc == NULL)

    37.                         {

    38.                                 pthread_mutex_lock(&counter_mutex); //mutex 保护临界区

    39.                                 if(myc == NULL) //两次检查

    40.                                 {

    41.                                         myc = new single_ins;

    42.                                         cnt++;

    43.                                 }

    44.                                 pthread_mutex_unlock(&counter_mutex); //mutex结束

    45.                         }

    46.                         //懒汉式

    47.                         return myc;

    48.                 }

    49.                 static void  pfree()

    50.                 {

    51.                         if(myc != NULL)

    52.                         {

    53.                                 delete myc;

    54.                                 myc = NULL;

    55.                         }

    56.                 }

    57. };

    58. //懒汉式 init static value

    59. single_ins* single_ins::myc = NULL;

    60. int single_ins::cnt = 0;

    61. //饿汉试 init static value

    62. //single_ins* single_ins::myc = new single_ins;

    63. /*

    64.    懒汉式的问题在于多线程调用的时候会出现问题,很可能同时建立出多个内存空间,

    65.    而不是单列了。

    66.    */

    67. void* main21(void* argc)

    68. {

    69.         single_ins* inp = (single_ins*)argc;

    70.         inp = single_ins::setp();

    71.         inp->setval(10,20);

    72.         inp->print();

    73.         cout<<inp<<"\n";

    74.         return NULL;

    75. }

    76. int main(void)

    77. {

    78.         pthread_t tid;

    79.         single_ins* a[3] = {NULL};

    80.         void* tret[3] = {NULL};

    81.         for(int i = 0 ; i<3; i++)

    82.         {

    83.                 pthread_create(&tid,NULL,main21,(void*)a[i]);

    84.                 //pthread_join(tid, &(tret[i]));

    85.         }

    86.         sleep(50);

    87.         single_ins::pfree();

    88. }

    跑出的结果如下:

    con begin
    con end
    a:10a:10
    b:20
    1
    0x7f21f40008c0

    b:20
    1
    0x7f21f40008c0
    a:10
    b:20
    1
    0x7f21f40008c0

    现在就是正常的了。所以懒汉试单例遇到多线程一定要注意,饿汉试没有问题。
    当然这是一个小列子而已,线程安全是一个很大的话题,特别需要注意。

                   

    以上是“C++如何解决单例懒汉式和多线程问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

    内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/128604.html

    (0)

    相关推荐

    • OGG中主键与trandata的添加顺序是什么

      技术OGG中主键与trandata的添加顺序是什么本篇文章给大家分享的是有关OGG中主键与trandata的添加顺序是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一

      攻略 2021年11月12日
    • 优化SQL Server 索引的小技巧有哪些

      技术优化SQL Server 索引的小技巧有哪些优化SQL Server 索引的小技巧有哪些,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。在

      攻略 2021年12月1日
    • 如何使用Chrome DevTools调试JavaScript

      技术如何使用Chrome DevTools调试JavaScript这篇文章主要介绍了如何使用Chrome DevTools调试JavaScript,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有

      攻略 2021年10月30日
    • 如何使用Bytom-Mobile-Wallet-SDK?

      技术Bytom-Mobile-Wallet-SDK的使用方法是什么这篇文章主要介绍“Bytom-Mobile-Wallet-SDK的使用方法是什么”,在日常操作中,相信很多人在Bytom-Mobile-Wallet-SD

      攻略 2021年12月20日
    • 将文件压缩成PNG图像存储方法是什么

      技术将文件压缩成PNG图像存储方法是什么本篇内容介绍了“将文件压缩成PNG图像存储方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅

      攻略 2021年11月18日
    • 如何搭建linux及ubuntu以太坊私有链开发环境

      技术如何搭建linux及ubuntu以太坊私有链开发环境本篇文章给大家分享的是有关如何搭建linux及ubuntu以太坊私有链开发环境,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说

      攻略 2021年10月23日