lower_bound方法一般应用于排序的系列,比如vector、list等,在插入新的记录前通过这个方法找到插入点,当找不到插入点时追加到最后即可,由此可以生成排序的系列。同样使用这个方法可以找到系列中的某一对象,binary_search方法就是使用的这个方法。
今天我在测试一个项目时发现一个奇怪的现象,就是在多线程情况下通过这个方法查找某一对象时,系列中的某一个对象的值会发生变化,而变化的值有可能还会变成其它值,结果将会导致已排序的系列变成无序,后果可想而知。
假设系列中的每个元素是下面的结构:
typedef struct tagMbParam
{
std::string strParamName;
unsigned char nType;
unsigned short nPduAddr;
} MB_PARAM, *PMB_PARAM;
我们给lower_bound指定一个排序函数,按strParamName从小到大排序:
bool MBPSortFun(MB_PARAM first, MB_PARAM second)
{
if (first.strParamName < second.strParamName)
{
return true;
}
else
{
return false;
}
}
我们用下面的方法查找某一对象:
MB_PARAM mb;
mb.strParamName = "要查找对象对应的值";
系列类型::iterator it = lower_bound(系列.begin(), 系列.end(), mb, MBPSortFun);
在单线程时没有问题,在多线程情况下,系统中某一个元素中的strParamName会发生变化,导致问题出现。
我怀疑是不是lower_bound不支持多线程或支持得不够好,因此在该函数的调用前后加上临界区,问题不再出现:
EnterCriticalSection(&s_csParam);
系列类型::iterator it = lower_bound(系列.begin(), 系列.end(), mb, MBPSortFun);
LeaveCriticalSection(&s_csParam);