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

C++:多线程编程学习:利用多线程进行归并排序。

2016-09-08 20:24 411 查看

首先学习一下简单的线程知识

:(1)pthread_join函数,用来阻塞当前的线程。直到指定线程结束。

:(2)pthread_create,用来创建线程。

下面的代码开了五个线程用来输出一个函数。

#include <pthread.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include "unistd.h"
using namespace std;

#define NUM_THREADS 5

vector<int> 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;
}

void* say(void* thread_id)
{

auto tid = *((int*)(thread_id));
sleep(2*tid);
cout<<"hello, ID: "<<tid<<endl;
}
void* merge_sort(void * arg)
{

}
int main()
{
pthread_t tids[NUM_THREADS];//define the id of thread
int index[NUM_THREADS];
/*for(const auto &x : tids){
cout<<x<<endl;
}*/

pthread_attr_t attr;
void* status;
pthread_attr_init(&attr);// init attr
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);//set attr as not joinable
for(size_t i = 0;i!=NUM_THREADS;++i)
{
index[i] = i;
auto ret = pthread_create(&tids[i],NULL,say,(void*)(&index[i]));
if (ret){
cout<<"pthread_create error,error code = "<<ret<<endl;
}
}

pthread_attr_destroy(&attr);//destroy the attr and wait other thread
for(size_t i = 0;i<NUM_THREADS;++i)
{
auto ret = pthread_join(tids[i],&status);
if (ret){
cout<<"Error:unable to join "<<ret<<endl;
exit(-1);
}

cout<<"main: completed thread id "<<i<<endl;

}
pthread_exit(NULL);
//pthread_create(thread,NULL,merge_sort,)

return 0;
}


下面的代码则是用多线程进行归并排序,由于使用模板参数,该程序可以比较任意的类型的数据。下面说几个编程时遇到的问题



(1):似乎线程的目标函数必须是void* 类型的函数,否则编译不通过。

(2):在传输参数的时候,必须将参数封装在一个结构体里面,然后将结构体的指针转换成void*类型。

(3):因为我们要进行模板编程,所以要将结构体,以及相应的处理函数都写成模板的形式。

(4):将数据用vector表示而不是数组的形式,这样可用不需要知道数据的长度,结构体内部使用该vector的引用

(5):使用decltype()获取类型,如该使用decltype(a[0])的形式会获得一个引用的类型,这不是需要的,所以要利用decltype(a);

#include <pthread.h>
#include <iostream>
#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>
struct Leninfo
{
Leninfo(int _l,int _h,T& _arr):l(_l),h(_h),arr(_arr){}
int l;
int h;
T& arr;
};
vector<int> 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(void* info)// merge the arr[l]->arr[h-1]
{

auto arg = (Leninfo<T>*)(info);
size_t l = arg->l,h = arg->h;
T& arr = arg->arr;

if (h-l < 5) { sort(arr.begin()+l,arr.begin()+h);
return NULL;}

pthread_t tid1,tid2;
auto mid = (l+h)>>1;
Leninfo<T> info1 = Leninfo<T>(l,mid,arr),info2 = Leninfo<T>(mid,h,arr);

pthread_create(&tid1,NULL,merge_sort<T>,(void*)(&info1));  //merge_sort(l,mid);
pthread_create(&tid2,NULL,merge_sort<T>,(void*)(&info2));//merge_sort(mid,h);

void *status1,*status2;
pthread_join(tid1,&status1);
pthread_join(tid2,&status2);
my_merge(arr,l,mid,h);
}

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