Windows中同时打开巨多窗口的方法.

本文介绍如何通过修改Windows注册表中的GDI资源限制,增加可以创建的窗口数量,解决资源不足导致的电脑不稳定现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不知大家在平时使用电脑的时候是不是会打开很多的窗口, 但是我的确喜欢这样, 但windows在打开了很多的窗口的时候就会出现"不稳定"的现象. 诸如: 不能创建窗口, 窗口上的菜单忽然不能正常显示等等怪现象, 刚开始我也"认命"了, 以为真是资源不够了或是MS设了窗口数目上限了, 但总是感到不爽, 总觉得电脑资源被浪费了, 内存空闲那么多, 为什么就是不能再打开程序/窗口了呢(当时差不多已经打开了25个左右的窗口, 其中有5个VS.NET2003, 10个IE窗口). 而且觉得MS更不可能把这个数目定死啊, 以后扩展怎么办呢.
 
经过我大海捞针, 终于在注册表的一个地方发现了一个线索, 这个线索终于让我找到了罪魁祸首.
 
事情是这样di:
 
windows中的窗口要使用系统的一个资源--GDI资源, 资源数目越多, 可以创建的窗口也会越多. 如果系统中GDI资源用完, 窗口就自然不能正常显示了, 所以就会出现平时难以一见的怪现象(有时窗口上的一些组件会莫名其妙的消失了, 呵呵).
 
所以只要GDI资源足够多, 窗口就可以不断创建.
 
不幸的是MS果真做了一个限制:
对于Windows2000/XP, 系统默认情况下GDI资源的上限都是10000
 
但MS也没有做绝, 这个值的确可以修改.
这个值的为止在:
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Windows
这个键下有这样两个值:
GDIProcessHandleQuota 和 USERProcessHandleQuota
 
一看就明白了吧, 呵呵.
他们的默认值都是10000
这两个值的范围是:
Windows XP:  This value can be set to a number between 200 and 65,536.

Windows 2000:  This value can be set to a number between 200 and 16,384.

 

MSDN如是说.

 

幸亏我用的是XP啊, 要不然我非得重装系统.

把这两个值都改成了50000, 重启了一下, 哇, 现在打开巨多窗口都正常了(总共最多同时打开了50左右的窗口), 真爽!!!

 

注意点:

两个值都要增加. 因为访问GDI资源得时候是通过句柄得, 所以句柄资源也要增加才行. 而且句柄资源还不光是用来访问GDI资源的.

 

这两个值修改后系统需要重启才能生效.

 

电脑配置要好一些, 推荐512MB内存, 虚拟内存也要设高点, 最好>2G.

 

 

此文谨献给跟我一样有这样"癖好"的人, ^_^.

如有错误之处请赶快指出, 要不然就误人子弟了, 哈哈.

<think>我们正在讨论在行为树中维护结构体时,仅考虑形参传递,比较`updateCellOrder`和`setRoomMap`两种函数写法的优劣。核心点:在行为树中,我们通常将数据存储在黑板(Blackboard)中,而行为节点通过读写黑板来传递数据。因此,函数的参数传递方式(尤其是传递结构体)会影响效率。两个函数的签名:1.`boolupdateCellOrder(RoomCleanInfo&room_clean_info);`输入输出都通过一个非const引用`room_clean_info`来传递。函数内部直接修改这个结构体的成员(如cell_order,cell_rank_)。2.`boolsetRoomMap(HouseCleanInfo&house_clean_info,RoomCleanInfo&room_clean_info);`同样通过两个非const引用来传递,并且其中一个参数是另一个房间的结构体(HouseCleanInfo),然后调用另一个重载函数(参数列表非常长)。但是,我们注意到`setRoomMap`的实现:```cppboolRoomCoverPlannerInterface::setRoomMap(HouseCleanInfo&house_clean_info,RoomCleanInfo&room_clean_info){returnsetRoomMap(house_clean_info.room_map_,house_clean_info.map_resolution_,house_clean_info.map_origin_,house_clean_info.map_origin_,house_clean_info.rotation_offset_,house_clean_info.room_direct_,room_clean_info.current_pose_,room_clean_info.room_map_,room_clean_info.map_resolution_,room_clean_info.map_origin_,room_clean_info.resize_room_map_,room_clean_info.origin_room_map_,room_clean_info.dilate_origin_room_map_,room_clean_info.cover_map_,room_clean_info.obstacle_map_,room_clean_info.cell_nav_map_,room_clean_info.rotate_matrix_map2rmap_,room_clean_info.bbox_,room_clean_info.robot_radius_as_int_,room_clean_info.base_line_y_,room_clean_info.clean_interval_as_int_,room_clean_info.start_from_ymin);}```实际上它调用了一个参数非常多的函数,这个函数有很多参数,而且都是按值传递或按const引用传递?注意:这里传递的是结构体内部的基本类型或对象,具体传递方式需要看函数声明。对比:方式1(updateCellOrder):-参数:1个结构体的非const引用-函数内部直接修改这个结构体的某些成员。方式2(setRoomMap):-参数:2个结构体的非const引用,然后调用一个参数多的函数(注意:这个被调用的函数参数列表有大约20个参数,而且很多参数是结构体的成员变量,按值或按引用传递?)我们在行为树中调用这些函数时,通常会将黑板中的结构体取出来,作为参数传入。考虑点:1.可读性:哪个更容易理解?2.可维护性:哪个更容易修改?3.性能:参数传递的开销(尤其是结构体较大时)详细分析:1.可读性:-`updateCellOrder`:函数接收一个结构体引用,函数名暗示更新单元顺序。阅读者知道这个函数会修改结构体中的一些成员(具体看函数定义或文档)。参数少,清晰。-`setRoomMap`:函数有两个参数(两个结构体),然后内部调用一个长参数列表的函数。函数名暗示设置房间地图,但是实际参数传递的细节很多,而且被调用的函数需要20多个参数,调用语句很长,可读性差。2.可维护性:-`updateCellOrder`:如果结构体`RoomCleanInfo`发生变化,比如需要增加一个成员来影响单元顺序,那么需要修改这个函数的实现(但影响范围较小)。-`setRoomMap`:如果`HouseCleanInfo`或`RoomCleanInfo`的结构有变化,那么我们需要修改两处:(1)修改这个函数的参数传递(即增加或减少传递给内部函数的参数)(2)内部函数`setRoomMap`(那个有20多个参数的)也需要修改参数列表。这导致维护困难,特别是参数数量很多时,容易出错。3.性能:-在C++中,传递结构体引用(或指针)是高效的方式,避免了整个结构体的复制。-对于`updateCellOrder`:传递一个结构体引用,开销很小。-对于`setRoomMap`:传递两个结构体引用,开销也不大(两个指针)。但是,在调用内部的那个长参数函数时,参数传递方式就变得重要了:注意:在`setRoomMap`的实现中,传递给内部函数的参数都是结构体的成员变量。这些成员变量可能是基本类型(如int,double),也可能是对象(如cv::Mat,std::vector)。对于基本类型,按值传递是廉价的;但对于大对象(如cv::Mat),按值传递会引发深拷贝还是浅拷贝?cv::Mat按值传递是浅拷贝(引用计数),所以开销不大。但如果是std::vector并且按值传递,就会发生拷贝(深拷贝),这会带来开销。然而,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值