C++:マルチスレッドプログラミング学習:マルチスレッドによる集計ソート.
まず簡単なスレッドの知識を学びます
: (1) pthread_join関数は、現在のスレッドをブロックするために使用されます.指定したスレッドが終了するまで.
: (2) pthread_create、スレッドを作成します.
次のコードは、関数を出力するために5つのスレッドを開きます.
次のコードは、テンプレートパラメータを使用するため、任意のタイプのデータを比較できるマルチスレッドで並べ替えられます.いくつかのプログラミングで発生した問題について説明します.
.
(1):スレッドのターゲット関数はvoid*タイプの関数でなければならないようです.そうしないと、コンパイルは通過しません.
(2):パラメータを転送するときは、パラメータを1つの構造体にカプセル化し、構造体のポインタをvoid*タイプに変換する必要があります.
(3):テンプレートのプログラミングを行うため,構造体と対応する処理関数をテンプレートの形式に書く.
(4):配列ではなくvectorでデータを表すことで、データの長さを知る必要がなく、構造体内部でそのvectorの参照を使用することができます.
(5):decltype()を使用してタイプを取得します.このdecltype(a[0])を使用すると参照のタイプが得られます.これは必要ではありませんので、decltype(a)を使用します.
: (1) pthread_join関数は、現在のスレッドをブロックするために使用されます.指定したスレッドが終了するまで.
: (2) pthread_create、スレッドを作成します.
次のコードは、関数を出力するために5つのスレッドを開きます.
#include
#include
#include
#include
#include
#include
#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: "<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<
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 = "<//destroy the attr and wait other thread
for(size_t i = 0;iauto ret = pthread_join(tids[i],&status);
if (ret){
cout<<"Error:unable to join "<exit(-1);
}
cout<<"main: completed thread id "<//pthread_create(thread,NULL,merge_sort,)
return 0;
}
次のコードは、テンプレートパラメータを使用するため、任意のタイプのデータを比較できるマルチスレッドで並べ替えられます.いくつかのプログラミングで発生した問題について説明します.
.
(1):スレッドのターゲット関数はvoid*タイプの関数でなければならないようです.そうしないと、コンパイルは通過しません.
(2):パラメータを転送するときは、パラメータを1つの構造体にカプセル化し、構造体のポインタをvoid*タイプに変換する必要があります.
(3):テンプレートのプログラミングを行うため,構造体と対応する処理関数をテンプレートの形式に書く.
(4):配列ではなくvectorでデータを表すことで、データの長さを知る必要がなく、構造体内部でそのvectorの参照を使用することができます.
(5):decltype()を使用してタイプを取得します.このdecltype(a[0])を使用すると参照のタイプが得られます.これは必要ではありませんので、decltype(a)を使用します.
#include
#include
#include
#include
#include
#include
#include
#include
#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(iif (first[i]else{arr[k++] = second[j++];}
}
while (iwhile (jtemplate<typename T>
void* merge_sort(void* info)// merge the arr[l]->arr[h-1]
{
auto arg = (Leninfo*)(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 info1 = Leninfo(l,mid,arr),info2 = Leninfo(mid,h,arr);
pthread_create(&tid1,NULL,merge_sort,(void*)(&info1)); //merge_sort(l,mid);
pthread_create(&tid2,NULL,merge_sort,(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<return 0;
}