C++ 11 多线程合并排序

C++ 11 Multithreaded Merge Sort

本文关键字:排序 合并 多线程 C++      更新时间:2023-10-16

我在macOS中尝试了以下代码,但出现编译错误。我的问题是在创建线程时将参数传递给函数的最佳方法是什么?

#include <iostream>
#include <vector>
#include <thread>
#include <utility>
#include <functional>
void merge(std::vector<int> &v, int l, int m, int r) {
    int i = l;
    int j = m + 1;
    std::vector<int> temp;
    while (i <= m && j <= r) {
        if (v.at(i) <= v.at(j)) {
            temp.push_back(v.at(i++));
        }
        else {
            temp.push_back(v.at(j++));
        }
    }
    while (i <= m) {
        temp.push_back(v.at(i++));
    }
    while (j <= r) {
        temp.push_back(v.at(j++));
    }
    std::copy(temp.begin(), temp.end(), v.begin() + l);
}
void mergesort(std::vector<int> &v, int l, int r) {
    if (l < r) {
        int m = (l + r) / 2;
        std::thread sort_thread1(mergesort, std::ref(v), l, m);
        std::thread sort_thread2(mergesort, std::ref(v), m + 1, r);
        sort_thread1.join();
        sort_thread2.join();
        merge(v, l, m, r);
    }
}
int main(void) {
    int n;
    std::vector<int> v;
    std::cin >> n;
    for (int i = 0; i < n; ++i) {
        int a;
        std::cin >> a;
        v.push_back(a);
    }
    mergesort(v, 0, n - 1);
    for (const int &a : v) {
        std::cout << a << " ";
    }
    std::cout << std::endl;
    return 0;
}

我在这里尝试了 clang 和 g++,但得到与以下相同的错误:

~/Desktop> g++-6 mergesort.cpp -std=c++11 -pthread
mergesort.cpp: In function 'void mergesort(std::vector<int>&, int, int)':
mergesort.cpp:31:62: error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<std::vector<int> >, int&, int&)'
         std::thread sort_thread1(mergesort, std::ref(v), l, m);
                                                              ^
In file included from mergesort.cpp:3:0:
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:128:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
       thread(_Callable&& __f, _Args&&... __args)
       ^~~~~~
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:128:7: note:   template argument deduction/substitution failed:
mergesort.cpp:31:62: note:   couldn't deduce template parameter '_Callable'
         std::thread sort_thread1(mergesort, std::ref(v), l, m);
                                                              ^
In file included from mergesort.cpp:3:0:
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:123:5: note: candidate: std::thread::thread(std::thread&&)
     thread(thread&& __t) noexcept
     ^~~~~~
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:123:5: note:   candidate expects 1 argument, 4 provided
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:117:5: note: candidate: std::thread::thread()
     thread() noexcept = default;
     ^~~~~~
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:117:5: note:   candidate expects 0 arguments, 4 provided
mergesort.cpp:32:66: error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, std::reference_wrapper<std::vector<int> >, int, int&)'
         std::thread sort_thread2(mergesort, std::ref(v), m + 1, r);
                                                                  ^
In file included from mergesort.cpp:3:0:
/usr/local/Cellar/gcc/6.3.0_1/include/c++/6.3.0/thread:128:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
       thread(_Callable&& __f, _Args&&... __args)
       ^~~~~~

第 31/32 行更改为:

    std::thread sort_thread1([&v, l, m] { mergesort(v, l, m); });
    std::thread sort_thread2([&v, m, r] { mergesort(v, m + 1, r); });

将得到它进行编译。

我认为这是不正确的:

输入:

5 4  3 2 1 0

输出

0 1 2 3 4 
编译器

说它couldn't deduce template parameter '_Callable',所以我们明确指定重载版本。

以下更改

// ...
typedef void (*mergesort_ptr_t)(std::vector<int> &v, int l, int r);
void mergesort(std::vector<int> &v, int l, int r) {
    if (l < r) {
        int m = (l + r) / 2;
        std::thread sort_thread1((mergesort_ptr_t)(mergesort), std::ref(v), l, m);
        std::thread sort_thread2((mergesort_ptr_t)(mergesort), std::ref(v), m + 1, r);
// ...

似乎工作。

编译器信息:

➜  Downloads g++ -std=c++11 sxkdzmtsort.cpp
➜  Downloads g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin