我是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;
}
有人知道我的节目有什么问题吗?
答案 0 :(得分:5)
无论好坏,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);