C++ 如何使用带有递归模板函数的线程

C++ 如何使用带有递归模板函数的线程,c++,multithreading,templates,c++11,C++,Multithreading,Templates,C++11,我一直在尝试使用线程优化排序算法(快速排序)。我知道它在std::sort()实现中已经相当不错了,但我正试图在我的计算机上通过优化来击败它,同时学习线程 所以,我的问题是,如何使用递归快速排序函数中的线程 函数如下(删除了对问题不重要的内容): 我还尝试对每个参数调用ref(arr)等,但我得到了相同的错误 编辑: 通过@MFontani尝试解决方案后,我可以编译,没有错误,但在运行时,我得到: Debug Error! Program: ...sktop\VisualStudio\Proj

我一直在尝试使用线程优化排序算法(快速排序)。我知道它在std::sort()实现中已经相当不错了,但我正试图在我的计算机上通过优化来击败它,同时学习线程

所以,我的问题是,如何使用递归快速排序函数中的线程

函数如下(删除了对问题不重要的内容):

我还尝试对每个参数调用ref(arr)等,但我得到了相同的错误

编辑: 通过@MFontani尝试解决方案后,我可以编译,没有错误,但在运行时,我得到:

Debug Error!

Program: ...sktop\VisualStudio\Projects\SpeedTester\Debug\SpeedTester.exe

R6010
- abort() has been called


(Press Retry to debug the application)

一次又一次地重复。最后,它以代码3退出。

您需要明确指出哪个是
T
模板参数:

thread t1(&quicksort<T>, arr, size, beginning, slow - 1);
线程t1(&quicksort,arr,size,start,slow-1);

否则编译器会看到您引用的是函数模板,而不是特定的专门化;它无法从任何地方推断出
t

您的主要问题可能是您需要
join()
生成的
线程。如果线程对象在没有先前的
join()
detach()
的情况下被销毁,则实现将调用
std::terminate()

您不希望
detach()
,因为您需要知道所有部分排序都已完成,才能完成整体排序,因此
join
ing是正确的做法

此外,您还可以改进以下几点:

  • 您不应该通过引用传递
    int
    s。对于简单的标量类型,按值传递更有效,从其他线程引用局部变量通常不是一个好主意(除非您有很好的理由和协议)
  • 你开始的线程太多了。分区后,两个子排序需要两个线程,但有三个线程:当前线程也会继续运行,因此应该只创建一个新线程,并在当前线程中执行另一个子排序。(和
    join()
    完成后连接另一部分。)
  • 当分区变小时,不应继续创建新线程。通常情况下,最好为快速排序设置一个截止大小,并对较小的大小使用非递归(如插入排序),因为递归开销会高于算法复杂性的好处。对于并发排序,一个类似的截止点甚至更为重要:线程的开销远远高于一个简单的递归调用,并且对于较小(和附近)的分区,线程将开始频繁地命中相同的缓存线,从而使速度进一步减慢
  • 不受限制地创建线程通常不是一个好主意。这最终将达到平台极限。您可能希望限制要使用的线程数(使用原子计数器),或者使用类似于
    std::async
    的默认启动策略,以避免启动的线程超过平台的处理能力

谢谢!使用@mfontani可以运行我的代码。谢谢你提供的额外信息!我一定会记住的。
Debug Error!

Program: ...sktop\VisualStudio\Projects\SpeedTester\Debug\SpeedTester.exe

R6010
- abort() has been called


(Press Retry to debug the application)
thread t1(&quicksort<T>, arr, size, beginning, slow - 1);