题
我有一个使用qsort
排序结构的MFC CArray
一些旧的代码,但我看到偶尔坠毁的可能的下降到多个线程同时调用qsort
。我使用的代码看起来是这样的:
struct Foo
{
CString str;
time_t t;
Foo(LPCTSTR lpsz, time_t ti) : str(lpsz), t(ti)
{
}
};
class Sorter()
{
public:
static void DoSort();
static int __cdecl SortProc(const void* elem1, const void* elem2);
};
...
void Sorter::DoSort()
{
CArray<Foo*, Foo*> data;
for (int i = 0; i < 100; i++)
{
Foo* foo = new Foo("some string", 12345678);
data.Add(foo);
}
qsort(data.GetData(), data.GetCount(), sizeof(Foo*), SortProc);
...
}
int __cdecl SortProc(const void* elem1, const void* elem2)
{
Foo* foo1 = (Foo*)elem1;
Foo* foo2 = (Foo*)elem2;
// 0xC0000005: Access violation reading location blah here
return (int)(foo1->t - foo2->t);
}
...
Sorter::DoSort();
我将重构这个可怕代码来使用std::sort
代替,但不知道是否以上实际上是不安全的?
编辑:Sorter::DoSort
实际上是静态函数,但不使用静态变量本身
EDIT2:该SortProc功能被改变以匹配实际的代码
解决方案
您的问题并不一定有什么做用线saftey。
的排序回调函数在指针的每个项目,而不是物品本身。既然你是排序Foo*
你真正想要做的是访问参数Foo**
,像这样的:
int __cdecl SortProc(const void* elem1, const void* elem2)
{
Foo* foo1 = *(Foo**)elem1;
Foo* foo2 = *(Foo**)elem2;
if(foo1->t < foo2->t) return -1;
else if (foo1->t > foo2->t) return 1;
else return 0;
}
其他提示
您SortProc没有返回正确的结果,这可能是由一些假设的数据,那么,整理您完成整理之后会导致内存损坏。你甚至可以导致快速排序为腐败,因为它试图排序,但当然以实现不同而不同。
有关的qsort比较函数必须返回负如果第一对象是小于第二,零,如果它们是相等的,并且正否则。您当前的代码永远只返回0或1,返回1,当您应该返回负。
int __cdecl Sorter::SortProc(const void* ap, const void* bp) {
Foo const& a = *(Foo const*)ap;
Foo const& b = *(Foo const*)bp;
if (a.t == b.t) return 0;
return (a.t < b.t) ? -1 : 1;
}
C ++并没有真正了解线程安全的任何保证。关于你可以说的最多的是,要么多个读取器或一个作家的数据结构将确定。各位读者和作家的任意组合,并且需要以某种方式连载访问。
既然你标记MFC
标记你的问题,我想你应该选择多线程运行时库中项目设置。
现在,你的代码是线程安全的,但没用,因为DoSort-方法只使用局部变量,甚至不返回任何东西。如果要排序的数据是分拣机的一员,那么它是不是安全地从多个线程调用该函数。在gerenal,阅读了关于重入,这可能会给你一个的想法是什么你需要看出来的。
什么使它线程安全的,你的对象是否是线程安全的,例如,使快速排序线程安全的,你必须确保任何写或读或和对象是线程安全的。
在并行线程手册页列出了不是线程安全所需的标准功能。的qsort不在其中,所以它需要是线程安全在POSIX
HTTP://www.kernel .ORG / DOC /人-页/在线/页/ man7 / pthreads.7.html
我找不到适用于Windows相当于名单,虽然如此,这是不是一个真正的回答你的问题。我会有点惊讶,如果它是不同的。
要知道什么是“线程安全的”,在这种情况下意味着,虽然。这意味着可以同时调用相同的功能上不同的阵列 - 通过的qsort是安全的,这并不意味着对相同数据的并发访问(它不是)
。作为警告的话,你可能会发现std::sort
是不一样快qsort
。如果您发现试图std::stable_sort
。
我曾经写过基于代码中的BWT压缩机提出了我马克·尼尔森博士多布斯,当我把它变成类我发现,经常sort
是慢了很多。 stable_sort
固定的速度的问题。