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

Renyi-Fan 阅读:37 2024-09-07 23:24:14 评论:0

我是 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); 


标签:多线程
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号