C++智能指针auto_ptr、unique_ptr、shared_ptr、weak_prt详解

news2024/10/6 18:22:24

目录

一.为什么要使用智能指针

二.auto_ptr

三.unique_ptr

四.shared_ptr

五.weak_ptr


智能指针均定义在头文件<memory>中:

#include<memory>

同时每种智能指针都是以类模板的方式实现 

一.为什么要使用智能指针

  C++的内存管理中,每当使用new来申请新的内存空间时,则必须使用delete来完成对应的内存释放。但是有些时候无法避免程序在还未执行到delete语句时就跳转了或者没有执行到最后的delete语句就返回了,如果我们不在每一个可能跳转或者返回的窗口前释放资源,则会造成内存的泄露。

  使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域时,类会自动调用析构函数,析构函数则会自动释放资源。

二.auto_ptr

1.auto_ptr由C++98引入,但从C++11开始,引入了unique_ptr来替代auto_ptr。

2.创建一个auto_ptr智能指针:

①.创建空的auto_ptr指针:

auto_ptr<TypeName> Name();
auto_ptr<TypeName> Name(nullptr);

②.创建一个auto_ptr指针同时明确其指向:

auto_ptr<TypeName> Name(new TypeName);
auto_ptr<TypeName> Name(new TypeName(value)); //初始化指针

eg:

auto_ptr<int> au(new int);

由此创建一个auto_ptr指针指针,其指向是可容纳一个整数的堆储存空间。

auto_ptr不支持数组,并且不要将该auto_ptr智能指针往容器中放。

  创建完auto_ptr指针并将指针指向某个对象后,使用方法与普通的指针类似, 可以通过对指针解引用获得指针所指的对象本身,也可以使用类成员函数get(),该函数显示返回auto_ptr指针指向的对象。

C++代码示例:

#include<iostream>
#include<memory>
#include<string>
using namespace std;

int main()
{
	auto_ptr<string> au(new string("GodFishhh"));
	cout << *au << endl;
	cout << au.get() << endl;
	cout << *(au.get()) << endl;

	system("pause");
	return 0;
}

程序运行结果: 

可知au.get()返回智能指针auto_ptr所指向对象的地址,而*(au.get())与*au的效果相同,得到的是指针指向的对象本身。

3.auto_ptr的弊端

①.auto_ptr支持operator=,为了确保指针所有者唯一,对auto_ptr指针使用赋值运算符会转移指针的所有权。

数组保存auto_ptr示例:

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;

int main()
{
	vector<auto_ptr<string>> v1(2);

	auto_ptr<string> a1(new string("GodFishhh"));
	auto_ptr<string> a2(new string("AFish"));

	v1[0] = a1;
	v1[1] = a2;

	//auto_ptr<string> au(new string);
	//au = v1[1];
    auto_ptr<string> au = v1[1]; //重载赋值运算符会分配内存,所以可以直接创建对象然后指向别处

	cout << (au.get()) << endl;
	cout << v1[1].get() << endl;

	system("pause");
	return 0;
}

程序运行结果:

  可知此时v1[1]的地址已被设置为NULL,其罪魁祸首就是语句auto_ptr<string> au = v1[1],此行代码使用auto_ptr类的赋值运算符,将v1[1]中的指针所有权转移,并将v1[1]的指针设置为空指针NULL。 

②.auto_ptr支持复制构造,为了确保指针所有者唯一,对auto_ptr指针使用复制构造会转移指针的所有权。

函数传参示例:

类成员作为参数按值传递时通过复制构造函数生成副本

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;

void test(auto_ptr<string>au) //参数是类名为auto_ptr<string>是类对象
{
	return;
}

int main()
{
	auto_ptr<string>au(new string("GodFishhh"));
	cout << "将auto_ptr对象au作为参数传入函数前:" << endl;
	cout << *(au.get())<< endl;

	cout << "将auto_ptr对象au作为参数传入函数后:" << endl;
	test(au);
	cout << *(au.get()) << endl;
	
	system("pause");
	return 0;
}

程序运行结果:

 程序出现了崩溃

   程序崩溃的原因在于此行代码test(au),执行test函数时传入实参auto_ptr<string>对象au,此举都会导致原变量au的指针所有权转移,导致此时实参au的指针已被设置为空NULL。

   基于上述原因,auto_ptr在C++11中被抛弃,引入的更加完善的智能指针unique_ptr。

三.unique_ptr

1.unique_ptr由C++11引入,旨在替代不安全的auto_ptr。

2.unique_ptr指针指向的堆内存无法与其他unique_ptr指针共享,因此每个unique_ptr指针都独自拥有对其堆内存空间的所有权。

3.创建一个unique_ptr智能指针:

①.创建空的unique_ptr指针:

unique_ptr<TypeName> Name():
unique_ptr<TypeName> Name(nullptr);

②.创建一个unique_ptr同时明确其指向:

unique_ptr<TypeName> Name(new TypeName);
unique_ptr<TypeName> Name(new TypeName(value));

eg:

unique_ptr<int> un(new int);

由此创建出了一个unique_ptr智能指针,其指向是可容纳一个整数的堆储存空间。 

4.由于unique_ptr类型指针不共享各自拥有的堆内存,因此C++11标准中的unique_ptr模板类没有提供拷贝构造函数,只提供了移动构造函数。

移动构造函数使用语法:

unique_ptr<int> un1(new int);
unique_ptr<int> un2(move(p4)); //使用移动构造函数
//unique_ptr<int> un3(un1); //使用复制构造函数,而unique_ptr堆内存不共享,无法使用

使用移动构造函数后,un2会获得un1所指堆空间的所有权,同时un1将变为空指针NULL。

 代码测试:

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;



int main()
{
	unique_ptr<string> un1(new string);
	cout << "使用移动构造函数前的un1:" << un1 << endl;
	unique_ptr<string> un2(move(un1));
	cout << "使用移动构造函数后的un1:" << un1 << endl;
	cout << "un2:" << un2 << endl;
	
	system("pause");
	return 0;
}

程序运行结果:

由结果可知此时作为移动构造函数参数的un1已经变为空指针NULL了。

5.默认情况下,unique_ptr指针采用default_delete<T>方法释放内存,同时我们也可以根据实际场景自定义释放规则,但与shared_ptr指针不同,为unique_ptr自定义释放规则只能采用函数对象的方式。

//自定义的释放规则
struct myDelete
{
    void operator()(int *p) 
   {
        delete p;
    }
};
unique_ptr<int, myDelete> p6(new int);
//unique_ptr<int, myDelte> p6(new int, myDel());

6.unique_ptr<T>模板类提供的成员方法:

unique_ptr指针可调用的成员函数

 同时C++11标准还支持unique_ptr指针之间,以及unique_ptr和nullptr之间做 ==,!”,<,<=,>,>=运算。

7.unique_ptr指针的基本用法(release(),reset() )示例:

C++代码:

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;


int main()
{
	unique_ptr<string> un1(new string("GodFishhh"));
	cout << "release前的un1:" << un1.get() << endl;
	//使用release函数转移智能指针unique_ptr所指堆空间的所有权
	string* s1 = un1.release();
	cout << "release后的un1:" << un1 << endl;
	cout << "s1:" << s1 << "||" << "*s1:" << *s1 << endl;

	unique_ptr<string> un2(new string("AFish"));
	//使用reset函数使得un2获得某个堆内存的所有权:
	cout << "reset前的s1/*s1:" << s1 <<"/"<<*s1<< endl;
	cout << "reset前的un2/*un2:" << un2 <<"/"<<*un2<< endl;
	un2.reset(s1);
	cout << "reset后的s1:" << s1 << endl;
	cout << "reset后的un2/*un2:" << un2 << "/" << *un2 << endl;

	system("pause");
	return 0;
}

程序运行结果:

  由程序运行结果可知release()函数会转移unique_ptr指针un1所指向的堆空间所有权,并将un1设置为空指针NULL。reset(p)函数会将调用该函数的unique_ptr对象所指向的堆空间释放,并获得参数指针所指堆空间内存的所有权(其中参数p是一个普通指针)。

四.shared_ptr

1.与unique_ptr和weak_ptr不同之处在于多个shared_ptr可以共同使用同一块堆内存。同时shared_ptr指针在实现上采用的是引用计数机制,即使有一个shared_ptr指针放弃了堆内存的使用权,导致引用计数减一,也不会影响其他指向同一堆内存的shared_ptr指针。(只有当引用计数为零时,即没有shared_ptr指针指向某块堆内存时,堆内存才会自动释放)

2.创建一个shared_ptr智能指针:

①.创建空的shared_ptr指针:

shared_ptr<TypeName> Name();
shared_ptr<TypeName> Name(nullptr);

②.创建一个shared_ptr指针并明确其指向:

shared_ptr<TypeName> Name(new TypeName);

eg:

shared_ptr<string> sh(new string(5));

 如上语句,我们就成功构建了一个shared_ptr智能指针,其指向一个存有五个string类型数据的堆内存空间

3.C++11标准提供make_shared<T>模板函数,用于初始化shared_ptr智能指针

shared_ptr<string> sh = make_shared<string>(5);

即构建了一个shared_ptr智能指针,其指向一个存有五个string类型数据的堆内存空间。

与如下创建方法相同:

shard_ptr<string> sh(new string(5));

4.shared_ptr<T>模板提供了相应的复制构造函数和移动构造函数

①.复制构造函数:

shared_ptr<int> sh1(sh2);

其中sh1和sh2均为shared_ptr智能指针。(sh2作为左值)

如果sh2为空智能指针,则sh1也同样为空智能指针。

如果sh2不是空智能指针,则表明sh1和sh2指向同一块堆内存空间,因此该堆空间的的引用计数会加一。 

②.移动构造函数:

shared_ptr<int> sh1(move(sh2));

move的参数sh2会被强制转换成对应的右值。

同时调用移动构造函数会使sh1获得sh2所指堆空间的所有权,而参数sh2则会变空智能指针。

eg:

C++代码示例:

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;


int main()
{
	shared_ptr<string> sh1(new string("GodFishhh"));
	cout << "移动构造之前的sh1:" << sh1.get() << endl;
	shared_ptr<string> sh2(move(sh1));
	cout << "移动构造之后的sh1:" << sh1.get() << endl;
	cout << "通过移动构造初始化的智能指针sh2:" << sh2 << endl;
	system("pause");
	return 0;
}

程序运行结果:

可知作为移动构造函数的智能指针参数sh1变为了空指针。

5.在初始化shared_ptr智能指针时,还可以自定义所指堆内存的释放规则,当堆内存的引用计数为0时,则会优先调用我们自定义的释放规则。

自定义堆内存释放规则:

//指定 default_delete 作为释放规则
//默认的shared_ptr指针内存释放方式
shared_ptr<int> sh1(new int[10], default_delete<int[]>());

//自定义释放规则
void deleteInt(int*p) 
{
    delete []p;
}
//初始化智能指针,并自定义释放规则
shared_ptr<int> sh2(new int[10], deleteInt);

 shared_ptr默认的释放规则是不支持数组的,若是申请的动态数组则必须通过自定义的释放规则来释放申请的堆内存

6.shared_ptr<T>模板类提供的成员方法:

shared_ptr<T>模板类常用方法:

除此之外,C++11 标准还支持同一类型的 shared_ptr 对象,或者 shared_ptr 和 nullptr 之间,进行 ==,!=,<,<=,>,>= 运算。

7.shared_ptr智能指针的基本用法示例:

C++代码:

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;


int main()
{
	//use.count()函数:返回当前shared_ptr对象指向相同的堆内存的shared_ptr对象数量
	//复制构造函数
	shared_ptr<string> sh1(new string("GodFishhh"));
	cout << "复制构造前的sh1/*sh1;" << sh1 << "/" << *sh1 << endl;
	cout << "sh1所指堆空间含有多少对象指向:" << sh1.use_count() << endl;
	shared_ptr<string> sh2(sh1);
	cout << "复制构造后的sh1/*sh1;" << sh1 << "/" << *sh1 << endl;
	cout << "通过复制构造初始化的sh2/*sh2" << sh2 << "/" << *sh2 << endl;
	cout << "sh1所指堆空间含有多少对象指向:" << sh1.use_count() << endl;
	cout << "-----------------------" << endl;

	//移动构造函数
	shared_ptr<string> sh3(new string("AFish"));
	cout << "移动构造前的sh3:" << sh3 << endl;
	cout << "sh3所指堆空间含有多少对象指向:" << sh3.use_count() << endl;
	shared_ptr<string> sh4(move(sh3));
	cout << "移动构造后的sh3:" << sh3 << endl;
	cout << "通过移动构造初始化的sh4:" << sh4 << endl;
	cout << "sh4所指堆空间含有多少对象指向:" << sh4.use_count() << endl;
	cout << "-----------------------" << endl;

	//reset()函数:当函数没有实参时,该函数会使当前shared_ptr所指堆内存的引用计数减一,同时将当前对象重置为一个空指针;当为函数传递一个新申请的堆内存时,则调用该函数的shared_ptr对象会获得该存储空间的所有权,并且引用计数的初始值为1
	//没有实参时:
	sh1.reset();
	cout << "调用没有参数的reset函数后的sh1:" << sh1 << endl;
	cout << "sh2所指堆空间含有多少对象指向:" << sh2.use_count() << endl;
	cout << "-----------------------" << endl;
	//有实参时:
	//shared_ptr<string> sh5(new string("Fish"));
	cout << "调用有参数的reset函数前的sh3所指空间有多少对象指向:" << sh3.use_count() << endl;
	cout << "调用有参数的reset函数前的sh3:" << sh3 << endl;
	sh3.reset(new string("Fish"));
	cout << "调用有参数的reset函数后的sh3所指空间有多少对象指向:" << sh3.use_count() << endl;
	cout << "调用有参数的reset函数前的sh3/*sh3:" << sh3 <<"/"<<*sh3<< endl;
	cout << "-----------------------" << endl;

	//swap():交换两个相同类型的shared_ptr智能指针的内容
	cout << "swap前的*sh2和*sh4:" << *sh2 << "  " << *sh4 << endl;
	sh2.swap(sh4);
	cout << "swap后的*sh1和*sh4:" << *sh2 << "  " << *sh4 << endl;
	cout << "-----------------------" << endl;

	//unique():判断当前shared_ptr对象所指的堆内存,是否不再有其他shared_ptr对象再指向它
	if (sh4.unique())
	{
		cout << "目前只有一个shared_ptr智能指针指向该堆空间" << endl;
	}
	else
	{
		cout << "目前有多个shared_ptr智能指针指向该堆空间" << endl;
	}
	cout << sh4.use_count() << endl;
	system("pause");
	return 0;
}

程序运行结果:

五.weak_ptr

1.weak_ptr智能指针通常不单独使用,只能和shared_ptr类型指针配合使用。weak_ptr类似于shard_ptr指针的一种辅助工具,借助weak_ptr指针,我们可以获得 shared_ptr指针的一些状态信息。

2.当weak_ptr指针的指向和某一个shared_ptr指针相同时,并不会使所指堆内存的引用计数加一;weak_ptr指针被释放时,也不会使所指堆内存的引用计数减一。因此,weak_ptr指针不会影响所指堆空间的引用计数。

3.创建一个weak_ptr智能指针

①.创建一个空的weak_ptr指针

weak_ptr<string> we();
weak_ptr<string> we(nullptr);

②.通过已有的weak_ptr指针创建一个新的weak_ptr指针

weak_ptr<string> we2(we1);

若we1为空指针,则we2也为空指针。

若we1不是空指针,则we1指向某一个shared_ptr指针拥有的堆内存,同时we2也指向该堆内存空间,但只能访问没有所有权。

③.利用已有的shared_ptr为weak_ptr指针初始化(weak_ptr指针通常指向某一shared_ptr指针拥有的堆内存)

shared_ptr<string> sh(new string);
weak_ptr<string> we(sh);

此时we和sh指针指向相同的堆内存空间,但是堆内存空间的引用次数不会改变。

3.weak_ptr<T>模板类提供的成员方法:

weak_ptr可调用的成员方法: 

 同时,weak_ptr<T> 模板类没有重载 * 和 -> 运算符,因此 weak_ptr 类型指针只能访问某一 shared_ptr 指针指向的堆内存空间,无法对其进行修改。

4.weak_ptr智能指针基本用法示例:

C++代码:

#include<iostream>
#include<memory>
#include<string>
#include<vector>
using namespace std;


int main()
{
	//use_count()查询与当前weak_ptr指针相同的shared_ptr指针的数量
	//通过shared_ptr指针初始化weak_ptr指针;
	shared_ptr<string> sh1(new string("GodFishhh"));
	shared_ptr<string> sh2(sh1);
	weak_ptr<string> we1(sh1);
	weak_ptr<string> we2(sh1);

	cout << "此时与we1指针相同的shared_ptr指针数量:" << we1.use_count() << endl;

	shared_ptr<string> sh3(sh1);

	cout << "此时与we1指针相同的shared_ptr指针数量:" << we1.use_count() << endl;
		
	//reset()将当前weak_ptr指针设为空指针
	we1.reset();

	//expire()判断当前weak_ptr指针是否过期(指针为空或者指针的堆内存已经释放)
	if (we1.expired())
	{
		cout << "weak_ptr指针we1已经过期" << endl;
	}
	else
	{
		cout << "weak_ptr指针we1没有过期" << endl;
	}
	if (we2.expired())
	{
		cout << "weak_ptr指针we1已经过期" << endl;
	}
	else
	{
		cout << "weak_ptr指针we1没有过期" << endl;
	}

	//lock()如果当前weak_ptr已经过期,则返回一个空的shared_ptr指针;反之,该函数返回一个和当前weak_ptr指向相同的shared_ptr指针
	shared_ptr<string> sh4 = we1.lock();
	cout << "we1.lock()的返回值sh4:" << sh4 << endl;
	shared_ptr<string> sh5 = we2.lock();
	cout << "we2.lock()的返回值sh5:" << sh5 << endl;
	cout << "sh1:" << sh1 << endl;
	system("pause");
	return 0;
}

程序运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用ArcGIS拼接栅格

1、概述数据的来源是多种多样的&#xff0c;特别是从网上下载的各种数据往往是分块的数据&#xff0c;在使用的时候需要进行数据的拼接&#xff0c;这里为大家介绍一下ArcGIS进行栅格拼接的方法&#xff0c;希望能对你有所帮助。2、直接拼接在ArcToolbox中点击“数据管理工具\栅…

某书x-s和web_session

开工发现某书web更新了,目前笔记信息接口: /api/sns/web/v1/feed 请求时headers中需要x-s、x-t,cookie中需要有web_session。 文章目录 web_sessionX-SJS代码Python代码web_session web_session和当前环境绑定,重新注册后浏览器中的ID也会更新。 其主要依赖的参数是webI…

WebDAV之葫芦儿·派盘 +Polaris Office

Polaris Office 支持WebDAV方式连接葫芦儿派盘。 推荐一款可以实现在Windows桌面PC,Mac,Android设备和iOS设备上同步的移动办公软件,还支持通过WebDAV添加葫芦儿派盘。 Polaris Office是一款功能全面的办公自动化套件,软件集成了

vue 动态组件component

这篇文章主要介绍了 vue 动态组件component &#xff0c;vue提供了一个内置的<component>,专门用来实现动态组件的渲染&#xff0c;这个标签就相当于一个占位符&#xff0c;需要使用is属性指定绑定的组件&#xff0c;想了解更多详细内容的小伙伴请参考下面文章的具体内容…

ChatGPT小白免费使用教程

本教程介绍chargpt使用教程 :不需要翻墙,不需要注册,也不需要缴纳费用 通过本教程您将会使用chargpt写代码 搜索问题写论文 。 我展示了两个问题 问题一 :用python写一个学生信息管理系统 问题二:用python进行中文分词

【iMessage苹果相册推】CSR邮箱必须与证书分属的AppID相同。 若是您可以在步伐中吸取令牌,则此步伐是成功的。

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

Echarts修改柱状图柱子的宽度

第009个点击查看专栏目录Echarts的柱状图通常我们不去设置柱子的宽度&#xff0c;都是以默认的状态来处理。柱条的宽度&#xff0c;不设时自适应。 series-bar. barWidth 自适应 设定值可以是绝对值例如 10 或者百分数例如 ‘60%’。百分数基于自动计算出的每一类目的宽度。 …

Mac使用Maven出现command not found的问题

问题 Maven一直使用的好好的&#xff0c;但某一天开始突然挂了&#xff0c;出现command not found的问题&#xff08;事后推测可能是在多次修改.bash_profile后导致的误删配置&#xff09; 尝试1&#xff1a;先是问度娘&#xff0c;得到的答案清一色的是添加如下行到.bash_pro…

第九层(11):STL之常用遍历算法

文章目录前情回顾常用算法常用遍历算法for_eachtransform下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后面不定期更新有关C/C语法&#xff0c;数据结构&#xff0c;算法…

Git基本信息和日常操作记录

文章目录一、Git1、干啥的2、Git 与svn 的区别二、Git操作记录注意2.1、配置别名2.2、初始化本地git仓库&#xff08;创建新仓库&#xff09;2.3、配置用户名2.4、配置邮件2.4、clone远程仓库2.5、查看配置2.6、暂存修改撤回2.7、配置 git log 日志快捷命令2.8、git 自定义配置…

一刷代码随想录——二叉树

理论基础【1】分类满二叉树完全二叉树优先级队列其实是一个堆&#xff0c;堆就是一棵完全二叉树&#xff0c;同时保证父子节点的顺序关系。二叉搜素树二叉搜索树是有数值的&#xff0c;二叉搜索树是一个有序树。平衡二叉搜素树&#xff08;AVL&#xff09;C中map、set、multima…

Allegro走线规则管理器中网络不会被同步高亮的解决办法

Allegro走线规则管理器中网络不会被同步高亮的解决办法 在用Allegro做PCB设计的时候,在走线的时候,规则管理器中的网络能被高亮起来的话会十分直观,尤其是在做等长设计的时候。 但是有时候会遇到走线的时候,规则管理器中的网络不会同步高亮的情况 如下图: 下面介绍遇到这…

Baklib教您:如何构建有效的帮助中心知识库?

好的帮助中心网站架构良好并精心呈现&#xff0c;使客户可以轻松浏览网站并找到他们要搜索的内容。帮助中心应始终易于搜索&#xff0c;为客户提供品牌知识库的可访问版本&#xff0c;该帮助中心应以用户体验为核心。该站点通常会包含常见问题解答、文章和各种说明&#xff0c;…

SNMP源码分析

源码下载 http://www.net-snmp.org/download.html 源码目录结构 net-snmp程序逻辑 &#xff08;1&#xff09;main主函数 #ifdef WIN32SERVICE //windows系统下使用snmp static int SnmpDaemonMain(int argc, TCHAR * argv[]) #else //linux系统 int main(int argc, char …

吊打面试官,四面拿到阿里、字节 offer 后我还是选择了美团

祸兮福之所倚福兮祸之所伏 上学的时候对这句话不以为然&#xff0c;但是在社会上走的时间越长越觉得有道理 前不久好兄弟和领导闹矛盾裸辞了&#xff0c;身为好兄弟的我总不能干看着吧&#xff0c;总要帮他找工作的。(你们应该不会想我和他一起裸辞吧) 大学的师兄有好几个在大…

西门子200smart与组态王之间无线Profinet通信实例

在实际系统中&#xff0c;车间里分布多台PLC&#xff0c;需要用上位机软件集中控制。通常所有设备距离在几十米到上百米不等。在有通讯需求的时候&#xff0c;如果布线的话&#xff0c;工程量较大且不美观&#xff0c;这种情况下比较适合采用无线通信方式。本方案以组态王和2台…

19 | Rancher 使用介绍(管理 K8s 平台)

目录1 Rancher简介2 Rancher 安装2.1查看k8s的版本2.2 通过 Docker 来进行安装2.3 在 Rancher 的界面上绑定 K8s2.3.1 配置 Kubernetes 集群2.3.2 导入集群2.3.3 集群列表3 Rancher 上部署应用1 Rancher简介 Rancher 提供的功能&#xff1a; 支持 K8s 集群的身份验证和基于角色…

pod内时间时区与宿主机不一致

原因&#xff1a;pod内默认时区是UTC&#xff0c;宿主机时区是CST解决方式&#xff1a;一&#xff0c;如果仅仅是运行一个jar文件&#xff0c;可以使用如下命令&#xff1a;java -jar -Duser.timezoneGMT08 xxx.jar在k8s的Deployment文件中&#xff0c;加入上述JVM启动参数&…

一文读懂I/O模型

什么是IO呢&#xff1f;什么是阻塞非阻塞IO&#xff1f;什么是同步异步IO&#xff1f;什么是IO多路复用&#xff1f;select/epoll跟IO模型有什么关系&#xff1f;有几种经典IO模型呢&#xff1f;BIO、NIO、AIO到底有什么区别的&#xff1f; 如果这些问题&#xff0c;你都能很好…

hjr-微服务(六):如何保障服务稳定性

服务稳定是一个特别大的话题&#xff0c;一般我们用SLA描述服务的质量 SLA一般有99.9 &#xff0c;99.99&#xff0c;就是我们常说的三个9&#xff0c;四个9 有两个纬度衡量 时间纬度 请求纬度 请求的成功率计算方式&#xff1a;SL A 成功请求/&#xff08;成功请求请求失败…