multithreading - C++ 11 多线程归并排序

标签 multithreading c++11 mergesort

我是 C++11 的新手,我试图用 C++11 中的线程编写一个简单的程序。我进行了归并排序,以下是我的代码:

#include <iostream>
#include <thread>
#include <vector>
using namespace std;

void merge(vector<int>& vec, int start, int mid, int end)
{
    vector<int> one (vec.begin() + start, vec.begin() + mid + 1);
    vector<int> two (vec.begin() + mid + 1, vec.begin() + end + 1);

    int a = 0;
    int b = 0;
    int index = start;
    while (a < one.size() && b < two.size())
    {
        if (one[a] < two[b])
            vec[index ++] = one[a ++];
        else 
            vec[index ++] = two[b ++];
    }

    // merge the left-over elements
    while (a < one.size())
        vec[index ++] = one[a ++];
    while (b < two.size())
        vec[index ++] = two[b ++];
}

void merge_sort(vector<int>& vec, int start, int end)
{
if (start >= end)
    return;

int mid = start + (end - start) / 2;

// multi-thread version
thread first(merge_sort, vec, start, mid);
thread second(merge_sort, vec, mid + 1, end);
first.join();
second.join();

/*
// single-thread version, testified.
merge_sort(vec, start, mid);
merge_sort(vec, mid + 1, end); 
*/

merge(vec, start, mid, end);
}


int main()
{
    int a[] = {4, 2, 5, 9, 7, 1, 3};
    vector<int> vec(a, a + 7);
    merge_sort(vec, 0, 6);
    for (int i = 0; i < 7; i ++)
        cout << vec[i] << endl;
    return 0;
}

底层算法非常简单:将一个数组拆分为两个子数组后,创建了两个线程来处理子数组,一个线程对应一个子数组。加入两个线程后,合并两个子数组。
当我尝试在 MacOS 10.9.4 上使用 clang++ 5.1 编译它时,出现了以下错误:
Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:332:5:
error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);

然后我上网发现了一个类似的程序,它使用pthread,而不是C++11线程,底层逻辑几乎相同。我编译并运行了该程序,它运行良好。它看起来像这样:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
using namespace std;

#define N 2  /* # of thread */

int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};  /* target array */

/* structure for array index
 * used to keep low/high end of sub arrays
 */
typedef struct Arr {
    int low;
    int high;
} ArrayIndex;

void merge(int low, int high)
{
        int mid = (low+high)/2;
        int left = low;
        int right = mid+1;

        int b[high-low+1];
        int i, cur = 0;

        while(left <= mid && right <= high) {
                if (a[left] > a[right])
                        b[cur++] = a[right++];
                else
                        b[cur++] = a[right++];
        }

        while(left <= mid) b[cur++] = a[left++];
        while(right <= high) b[cur++] = a[left++];
        for (i = 0; i < (high-low+1) ; i++) a[low+i] = b[i];
}

void * mergesort(void *a)
{
        ArrayIndex *pa = (ArrayIndex *)a;
        int mid = (pa->low + pa->high)/2;

        ArrayIndex aIndex[N];
        pthread_t thread[N];

        aIndex[0].low = pa->low;
        aIndex[0].high = mid;

        aIndex[1].low = mid+1;
        aIndex[1].high = pa->high;

        if (pa->low >= pa->high) return 0;

        int i;
        for(i = 0; i < N; i++) pthread_create(&thread[i], NULL, mergesort, &aIndex[i]);
        for(i = 0; i < N; i++) pthread_join(thread[i], NULL);

        merge(pa->low, pa->high);

        //pthread_exit(NULL);
        return 0;
}

int main()
{
        ArrayIndex ai;
        ai.low = 0;
        ai.high = sizeof(a)/sizeof(a[0])-1;
        pthread_t thread;

        pthread_create(&thread, NULL, mergesort, &ai);
        pthread_join(thread, NULL);

        int i;
        for (i = 0; i < 10; i++) printf ("%d ", a[i]);
        cout << endl;

        return 0;
}

有人知道我的程序出了什么问题吗?

最佳答案

无论好坏,std::bind , std::async ,以及 std::thread构造函数将它们的参数复制到单独的存储中,以将它们的生命周期与当前作用域解耦。如果你真的想传递一个引用,你需要把它包裹在一个 reference_wrapper 中。与 std::ref (或 std::cref 用于 const 引用):

thread first(merge_sort, std::ref(vec), start, mid);
thread second(merge_sort, std::ref(vec), mid + 1, end);

关于multithreading - C++ 11 多线程归并排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25750066/

相关文章:

JavaFX 使用非 JavaFX 线程的 UI 中使用的提取器更新 ObservableList

java - Mergesort这个合并函数占用O(1)空间还是O(n)空间?

C 和 OpenMP : nowait for loop in a do loop

c# - 测试基于 C# 套接字的多线程服务器

c# - C# 编译器会优化变量吗?

c++ - make_shared 创建 std::shared_ptr?海湾合作委员会 4.6.2

c++ - Clang 未知类名 'exception'

c++ - 如何使 QGraphicsItem 的位置依赖于另一个 QGraphicsItem?

python - Python 3 中的递归

algorithm - 如何找出最大的元素个数(数组大小),让插入排序打败归并排序?