できれば非常に簡単な質問がありますが、オンラインで答えを見つけることができません。私はマージソート機能を作成しました(これは確かに非効率的です)が、スレッドについて尋ねるためにここにいます。Windows の CreateThread 関数を使用してスレッドを生成し、特定の配列の間隔を並べ替えています。すべてのスレッドが終了したら、最終結果のためにセグメントをマージします。スレッドのばかげた間違いによる奇妙なエラーが発生するため、最終的なマージはまだ実装していません。親切にparaMSortを見ていただければ、私のコードを投稿します。ヘルパー関数も確認できるように、MergeSort.h ファイル全体を投稿します。場合によっては、コードが完全にコンパイルおよび実行されることがあります。エラーや例外が発生することなく、コンソールが突然終了することがあります。配列の異なるセグメントで操作を行っているため、ミューテックスの問題は発生しないはずです(完全に異なるメモリ位置)。誰かが何か間違っていると思いますか?本当にありがとう。
PS。Windows CreateThread のカーネル レベルですか? つまり、デュアル コア コンピュータで 2 つのスレッドを作成した場合、それらは別々のコアで同時に実行できますか? このコンピューターでは、2 つのスレッドで 1/2 の時間で同じ作業を実行できるため (別のテスト例を使用)、私はそう考えています。
PPS。また、Boost.Thread を使用して解決された並列処理の回答も見ました。Windows スレッドの代わりにブースト スレッドを使用する必要がありますか? ブーストの経験がありません。
#include "Windows.h"
#include <iostream>
using namespace std;
void insert_sort(int* A, int sA, int eA, int* B, int sB, int eB)
{
int value;
int iterator;
for(int i = sA + 1; i < eA; i++)
{
value = A[i]; // Grab the next value in the array
iterator = i - 1;
// Move this value left up the list until its in the right spot
while(iterator >= sA && value < A[iterator])
A[iterator + 1] = A[iterator--];
A[iterator + 1] = value; // Put value in its correct spot
}
for(int i = sA; i < eB; i++)
{
B[i] = A[i]; // Put results in B
}
}
void merge_func(int* a, int sa, int ea, int* b, int sb, int eb, int* c, int sc)
{
int i = sa, j = sb, k = sc;
while(i < ea && j < eb)
c[k++] = a[i] < b[j] ? a[i++] : b[j++];
while(i < ea)
c[k++] = a[i++];
while(j < eb)
c[k++] = b[j++];
}
void msort_big(int* a, int* b, int s, int e, bool inA)
{
if(e-s < 4)
{
insert_sort(a, s, e, b, s, e);
return; // We sorted (A,s,e) into (B,s,e).
}
int m = (s + e)/2;
msort_big(a, b, s, m, !inA);
msort_big(a, b, m, e, !inA);
// If we want to merge in A, do it. Otherwise, merge in B
inA ? merge_func(b, s, m, b, m, e, a, s) : merge_func(a, s, m, a, m, e, b, s);
}
void msort(int* toBeSorted, int s, int e)
// Sorts toBeSorted from [s, e+1), so just enter [s, e] and
// the call to msort_big adds one.
{
int* b = new int[e - s + 1];
msort_big(toBeSorted, b, s, e+1, true);
delete [] b;
}
template <class T>
struct SortData_Send
{
T* data;
int start;
int end;
};
DWORD WINAPI msort_para_callback(LPVOID lpParam)
{
SortData_Send<int> dat = *(SortData_Send<int>*)lpParam;
msort(dat.data, dat.start, dat.end);
cout << "done! " << endl;
}
int ceiling_func(double num)
{
int temp = (int)num;
if(num > (double)temp)
{
return temp + 1;
}
else
{
return temp;
}
}
void paraMSort(int* toBeSorted, int s, int e, int numThreads)
{
HANDLE threads[numThreads];
DWORD threadIDs[numThreads];
SortData_Send<int>* sent[numThreads];
for(int i = 0; i < numThreads; i++)
{
// So for each thread, make an interval and pass the pointer to the array of ints.
// So for numThreads = 3 and array size of 0 to 99 (100), we have 0-32, 33-65, 66-100.
// 100 because sort function takes [start, end).
sent[i] = new SortData_Send<int>;
sent[i]->data = toBeSorted;
sent[i]->start = s + ceiling_func(double(i)*(double)e/double(numThreads));
sent[i]->end = ceiling_func(double(i+1)*double(e)/double(numThreads)) + ((i == numThreads-1) ? 1 : -1);
threads[i] = CreateThread(NULL, 0, msort_para_callback, sent[i], 0, &threadIDs[i]);
}
WaitForMultipleObjects(numThreads, threads, true, INFINITE);
cout << "Done waiting!" <<endl;
}