C++如何解决单例懒汉式和多线程问题
这篇文章主要为大家展示了“C++如何解决单例懒汉式和多线程问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C++如何解决单例懒汉式和多线程问题”这篇文章吧。
在宝安等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站建设、网站制作 网站设计制作定制开发,公司网站建设,企业网站建设,成都品牌网站建设,营销型网站建设,成都外贸网站建设,宝安网站建设费用合理。
单例懒汉式和多线程问题
作为单例模式,是在整个程序运行期间只会建立一份内存空间,为了达到这个目标
1、需要将构造函数设置为私有成员
2、需要一个私有的静态指针指向自身
3、需要一个公有的静态函数将这个上面的静态指针露出来
如下的代码就是一个懒汉式的单例
点击(此处)折叠或打开
#include
using namespace std;
class single_ins
{
private:
int a;
int b;
single_ins()
{
a= 0;
b= 0;
}
static single_ins* myc;
public:
void setval(const int& a,const int& b)
{
this->a = a;
this->b = b;
}
void print()
{
cout<<"b:"<
}
static single_ins* setp()
{
//?
if(myc == NULL)
{
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();
single_ins::pfree();
}
但是上面的代码有明显的问题,就是遇到多线程的情况下,因为多个线程如果同事创建内存,由于彼此之间
并不能及时检查到内存已经分配,会分配多个内存,这个时候我们至少需要一个线程间同步手段来让他们之间
串行的执行,这个时候就涉及到两次检查(double check)
如果没有mutex保护就是下面这个程序:
点击(此处)折叠或打开
#include
#include
using namespace std;
//单列模式
class single_ins
{
private:
int a;
int b;
single_ins()
{
cout<<"con begin\n";
a= 0;
b= 0;
sleep(10); //故意拖长构造函数执行时间,造成懒汉式多线程问题
cout<<"con end\n";
}
static single_ins* myc;//单例需要一个静态指针
static int cnt;//构造调用次数统计
public:
void setval(const int& a,const int& b)
{
this->a = a;
this->b = b;
}
void print()
{
cout<<"b:"<
cout<
}
static single_ins* setp() //函数获得指针值赋给静态成员指针变量
{
//懒汉式
if(myc == NULL)
{
myc = new single_ins;
cnt++;
}
//懒汉式
return myc;
}
static void pfree()
{
if(myc != NULL)
{
delete myc;
myc = NULL;
}
}
};
//懒汉式 init static value
single_ins* single_ins::myc = NULL;
int single_ins::cnt = 0;
//饿汉试 init static value
//single_ins* single_ins::myc = new single_ins;
/*
懒汉式的问题在于多线程调用的时候会出现问题,很可能同时建立出多个内存空间,
而不是单列了。
*/
void* main21(void* argc)
{
single_ins* inp = (single_ins*)argc;
inp = single_ins::setp();
inp->setval(10,20);
inp->print();
cout<
return NULL;
}
int main(void)
{
pthread_t tid;
single_ins* a[3] = {NULL};
void* tret[3] = {NULL};
for(int i = 0 ; i<3; i++)
{
pthread_create(&tid,NULL,main21,(void*)a[i]);
//pthread_join(tid, &(tret[i]));
}
sleep(50);
single_ins::pfree();
}
会跑出结果
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 }
这样代码如下:
点击(此处)折叠或打开
#include
#include
using namespace std;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
//单列模式
class single_ins
{
private:
int a;
int b;
single_ins()
{
cout<<"con begin\n";
a= 0;
b= 0;
sleep(10); //故意拖长构造函数执行时间,造成懒汉式多线程问题
cout<<"con end\n";
}
static single_ins* myc;//单例需要一个静态指针
static int cnt;//构造调用次数统计
public:
void setval(const int& a,const int& b)
{
this->a = a;
this->b = b;
}
void print()
{
cout<<"b:"<
cout<
}
static single_ins* setp() //函数获得指针值赋给静态成员指针变量
{
//懒汉式
if(myc == NULL)
{
pthread_mutex_lock(&counter_mutex); //mutex 保护临界区
if(myc == NULL) //两次检查
{
myc = new single_ins;
cnt++;
}
pthread_mutex_unlock(&counter_mutex); //mutex结束
}
//懒汉式
return myc;
}
static void pfree()
{
if(myc != NULL)
{
delete myc;
myc = NULL;
}
}
};
//懒汉式 init static value
single_ins* single_ins::myc = NULL;
int single_ins::cnt = 0;
//饿汉试 init static value
//single_ins* single_ins::myc = new single_ins;
/*
懒汉式的问题在于多线程调用的时候会出现问题,很可能同时建立出多个内存空间,
而不是单列了。
*/
void* main21(void* argc)
{
single_ins* inp = (single_ins*)argc;
inp = single_ins::setp();
inp->setval(10,20);
inp->print();
cout<
return NULL;
}
int main(void)
{
pthread_t tid;
single_ins* a[3] = {NULL};
void* tret[3] = {NULL};
for(int i = 0 ; i<3; i++)
{
pthread_create(&tid,NULL,main21,(void*)a[i]);
//pthread_join(tid, &(tret[i]));
}
sleep(50);
single_ins::pfree();
}
跑出的结果如下:
con begin
con end
a:10a:10
b:20
1
0x7f21f40008c0
b:20
1
0x7f21f40008c0
a:10
b:20
1
0x7f21f40008c0
现在就是正常的了。所以懒汉试单例遇到多线程一定要注意,饿汉试没有问题。
当然这是一个小列子而已,线程安全是一个很大的话题,特别需要注意。
以上是“C++如何解决单例懒汉式和多线程问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!
分享文章:C++如何解决单例懒汉式和多线程问题
网页地址:http://hbruida.cn/article/isghoc.html