Visual C++优化对大型数据集合的并发访问
2010-08-22 20:47:32 来源:WEB开发网我的针对这一问题的解决方案是封装在 CritSecTable 类中(参见图 11 和图 12)。该类的接口看起来几乎与 CritSec 的接口完全相同,不同之处在于 acquire 和 release 方法采用 void* 参数。
Figure 13 DBEntry Class
bool DBEntry::g_useSingleCritSec = true;
CritSec DBEntry::g_singleCritSec;
CritSecTable DBEntry::g_critSecTable;
void DBEntry::acquire()
{
if (g_useSingleCritSec)
{
g_singleCritSec.acquire();
}
else
{
g_critSecTable.acquire(this);
}
}
void DBEntry::release()
{
if (g_useSingleCritSec)
{
g_singleCritSec.release();
}
else
{
g_critSecTable.release(this);
}
}
要使用该类,需要将一个 CritSecTable 实例与您希望对其进行并发访问的大型集合(在这种情况下,即内存中的数据库)相关联。当您希望锁定或取消锁定某个项时,需要分别在 CritSecTable 对象上调用 acquire 或 release,并将该项的地址作为 void* 参数进行传递。有关示例,请参见 DBEntry 类的 acquire 和 release 方法的实现(如图 13 所示)。(我已经实现了这些方法,以便它们可以为整个数据库使用单个临界区,或者使用一个 CritSecTable,具体取决于全局标志 g_useSingleCritSec 的设置。)
CritSecTable 在内部维护了一个 CritSec 实例数组(在我的实现中,包含 256 个实例)。当您调用 acquire 或 release 时,它将根据该 void* 参数计算一个哈希,然后使用该哈希对数组进行索引,并在相应的 CritSec 对象上调用 acquire 或 release。这意味着对于任何给定的数据库项,您都将始终使用同一个 CritSec 对象,从而保证您能够保持正确的同步行为。
如果两个线程试图同时锁定不同的项,则其中一个线程阻塞另一个线程的可能性非常低(二百五十六分之一的可能性)。当然,随着试图对数据库进行并发访问的线程数的增加,其中一个或多个线程被阻塞的可能性也将增加。然而,在 Windows 中这通常不是一个问题。运行 Windows 的计算机很少具有八个以上的 CPU,并且(据我所知)上限是 32 个。如果您的服务器应用程序正在使用 I/O 完成端口(正像它应该做的那样),则在任意给定时间,您的服务器中正在运行的线程数目将接近于 CPU 的数目。(注:有关 I/O 完成端口的讨论超出了本文的范围,但最近几年来 MSDN Magazine 中出现过几篇有关该主题的好文章。
我选择使 CritSec 数组的长度为 256,因为它有利于使用一个非常简单但有效的哈希函数。在此情况下,该哈希函数只是简单地对 void* 的字节进行 XOR 运算,从而得到单个无符号 char。我已经花费了一些时间,针对 void* 的长度为四个字节、八个字节的情况以及一般性情况(针对您恰好在具有 7 字节指针的系统上运行 Windows 的情形)优化该哈希函数。在 32 位 Intel 系统上,Visual C++ 编译器将哈希方法的 32 行 C++ 代码简化为只有六条汇编语言指令。
如果您的应用程序将具有数量大得多的线程试图同时锁定不同的项,则您可能需要更大的 CritSec 数组,但您将需要更为复杂的哈希函数来对其进行哈希运算。
并发性结果
我在具有一个 CPU 的 500 MHz Pentium III 计算机上以及具有四个 CPU 的 550 MHz Pentium III Xeon 计算机上运行了 CD 示例。在每种情况下,我都使用不断增加的辅助线程数目运行了两个测试(一个使用单个临界区,另一个使用 CritSecTable)。图 14 显示了在单 CPU 计算机上使用一到八个辅助线程运行测试的结果。
图 14 单 CPU 计算机上的结果
- ››Visual Basic 2008 数学函数
- ››Visual Studio2005中Smart Device的问题
- ››Visual Studio 中根据数据库字段动态生成控件
- ››Visual Studio 11全新黑色主题
- ››Visual Studio 2011 Beta新特性(一):安装VS201...
- ››Visual Studio自定义调试窗体两个小技巧
- ››Visual Studio 2005 Team Edition for Database P...
- ››Visual C#两分钟搭建BHO IE钩子
- ››Visual C++优化对大型数据集合的并发访问
- ››优化精髓之商业性网站常遇见的问题和误区
- ››大型网站的域名分布策略
- ››优化增强您的Visual C++应用程序
更多精彩
赞助商链接