本文主要给大家展示“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保护就是下面这个程序:
点击(此处)折叠或打开
-
#include <iostream>
-
#include <unistd.h>
-
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<<"a:"<<a<<endl;
-
cout<<"b:"<<b<<endl;
-
cout<<cnt<<endl;
-
}
-
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<<inp<<"\n";
-
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 <iostream>
-
#include <unistd.h>
-
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<<"a:"<<a<<endl;
-
cout<<"b:"<<b<<endl;
-
cout<<cnt<<endl;
-
}
-
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<<inp<<"\n";
-
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++如何解决单例懒汉式和多线程问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/128604.html