2015-12-06 2 views
1

Я новичок в изучении C++, и я пытаюсь реализовать многопоточную версию MergeSort. Я сравнил свои алгоритмы с многочисленными реализациями онлайн и, похоже, почти идентичен, однако я не получаю правильный вывод. Выходной сигнал даже включает номера, не найденные в исходном входе.C++ Многопоточное слияние не работает

using namespace std; 
int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; /* target array */ 
int arrayLen; 

void merge(int low, int mid, int high) 
{ 
    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[left++]; 
     else 
      b[cur++] = a[right++]; 
    } 

    while(left <= mid) b[cur++] = a[left++]; 
    while(right <= high) b[cur++] = a[right++]; 
    cur--; 
    while (cur >= 0){ 
     a[low + cur] = b[cur]; 
     cur--; 
    } 
} 

void mergeSort(int p, int r){ 


    std::vector<std::future<void>> thread_poolLocal; 
    int q; 

    if (p >= r) return; 
    q = (p+r)/2; 

    thread_poolLocal.push_back(std::async(launch::async, mergeSort, p, q)); 
    thread_poolLocal.push_back(std::async(launch::async, mergeSort, q+1, r)); 

    merge(p, q, r); 
} 

int main() 
{ 
    arrayLen = (sizeof(a)/sizeof(*a)); 
    cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << endl; 

    int i; 
    for (i = 0; i < arrayLen; i++) printf ("%d ", a[i]); 
    cout << "\n" << endl; 
    mergeSort(0, arrayLen); 

    for (i = 0; i < arrayLen; i++) printf ("%d ", a[i]); 

    return 0; 
} 

Когда я проверить это с простым массивом, показанным выше, выход:

Length of array = 10 
10 9 8 7 6 5 4 3 2 1 

0 1 4 2 3 10 5 6 9 7 

Я компиляция программы с: g++ mergeSortThreaded.cpp -o mergeSortThreaded -std=c++0x -pthread

Что я здесь делаю неправильно?

ответ

0

Вы нажимаете 2 потока в thread_poolLocal, а затем сразу вызываете merge (которому нужны результаты этих потоков) до того, как потоки закончились.

Этот код может привести к взрыву потоков с сортировкой больших массивов, поскольку каждый вызов mergeSort создаст еще 2 потока, пока вы не спуститесь в пустые области.

+0

Есть ли способ, которым я могу дождаться завершения потоков до вызова слияния? Что касается взрыва потока, я знаю об этом, и я просто пытался заставить его работать, прежде чем рефакторинг этой части. Если я могу заставить потоки завершить выполнение перед вызовом слияния, это должно устранить проблему? Благодаря! – DonJuma

+0

@DonJuma Я не знаю стандартной функции для ожидания, но что-то похожее на строки 'for (auto & t: thread_poolLocal) t.wait();' должен делать трюк. Тем не менее, это не приведет к вылечению потока, поскольку это вызовы 'mergeSort', которые делают взрыва. – 1201ProgramAlarm

+0

Спасибо за ответ. Казалось, что это работает так, как ожидалось. Благодарю. Единственная проблема заключается в том, что отсортированный результат: 0,1,2,3,4,5,6,7,8,9. Откуда возникает нуль и почему исчезают 10? Это также результат того, что потоки не заканчиваются во времени? Я очень ценю всю помощь. – DonJuma

Смежные вопросы