您的位置:首页 > 编程语言 > C语言/C++

使用C++11进行多线程归并排序:std::thread

2016-09-12 20:57 567 查看

相对于使用pthread来说,c++的标准库对多线程的编程封装的非常好,使用起来有如下几个优势:

1:可以直接传递参数给函数,而不需要将它封装到一个结构体再转换成为void*传入。

2:对于目标函数的要求不再是void*的返回类型,这样如果要使用一些内置的函数,就不需要进行单独封装成void*类型。

======================================================

此外,编写下面的程序发现了以下几个要注意的地方.

1:首先,如果目标函数是模板,那么必须要显示模板化,因为编译器不知道目标函数的参数,thread函数会将它收到的参数拷贝之后转发给目标函数。所以编译的时候目标函数的类型不确定,这样就会导致出错。

2:其次,如该函数参数里面含有引用,那么必须要采用ref,因为thread是拷贝参数然后转发,所以必须如该利用std::ref,那么获取的参数就是拷贝的引用,这也会引起错误。

3:最后需要指出,因为thread默认是joinable的,所以不能在thread结束之前就结束调用它的线程。必须要加join.否则运行时会出现terminate without an active exception.

#include <iostream>
#include <thread>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <typeinfo>
#include <algorithm>
#include "unistd.h"
using namespace std;
#define NUM_THREADS 5

template<typename T>
vector<T> read_file(string filename)
{

ifstream file(filename);
int each_element;
vector<int> data;
if (file){
while(file>>each_element) {
data.push_back(each_element);
}
}
return data;
}

template<typename T>
void my_merge(T& arr,int l,int mid,int r)
{

size_t i = 0,j = 0,k = l;
size_t bound1 = mid-l,bound2 = r-mid;
T first;
T second;
for(size_t i = l;i!=mid;++i){first.push_back(arr[i]);}
for(size_t i = mid;i!=r;++i){second.push_back(arr[i]);}
while(i<bound1 & j<bound2)
{
if (first[i]<second[j]){ arr[k++] = first[i++];}
else{arr[k++] = second[j++];}
}

while (i<bound1){arr[k++] = first[i++]; }
while (j<bound2){arr[k++] = second[j++];}
}

template<typename T>
void merge_sort(size_t l,size_t h,T& arr)// merge the arr[l]->arr[h-1]
{
if (h-l < 5) {sort(arr.begin()+l,arr.begin()+h);
return ;}

size_t mid = (l+h)>>1;
thread sub_thread1(merge_sort<T>,l,mid,ref(arr));
thread sub_thread2(merge_sort<T>,mid,h,ref(arr));
sub_thread1.join();
sub_thread2.join();
my_merge(arr,l,mid,h);
}

int main()
{
vector<string> data = {"azcd","afgh","z","hijk","sdf","hlus"};
thread merge_(merge_sort<decltype(data)>,0,data.size(),ref(data));
merge_.join();
for(const auto &x : data){cout<<x<<endl;}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: