C ++-无法弄清楚如何使用互斥量计算线程

时间:2018-12-09 19:11:03

标签: c++ multithreading mutex mergesort

我正在用C ++编写多线程合并排序。上下文:用户使用适当的标志(例如, “ ./mergeSort 100 -t 20”

第一个数字代表程序应生成和排序的随机数,-t标志代表使用线程,最后一个数字代表程序应使用的最大线程数(当程序达到最大数量时)。线程,它继续执行标准的合并排序,而无需多线程)。

为了计算线程数,我使用了具有互斥锁的全局变量number_of_units,但是我一生都无法正确使用它。

标准合并排序功能将打印文本“标准”,而线程功能将打印出“新线程#”,其中#是程序仍可以创建的新线程数。每次启动新线程时,我都会递减计数器。这是main()的一个块:

cout << "array: ";
printArray(nums);
cout << endl;
mergeSortDirector(sort, nums, 0, nums.size() - 1);
cout << endl << "sorted array: ";
printArray(nums);

mergeSortDirector最初只是将程序定向到正确的排序,在这种情况下,将其定向到mergeSortThread:

void mergeSortThread(vector<int> &nums, int beg, int end) {

    cout << "new thread " << *number_of_units << endl;

    int mid;

    thread half1;
    thread half2;

    if (beg < end) {
        mid = (beg + end) / 2;

        if(*number_of_units > 1) {

            *number_of_units -= 2;
            mtx.lock();
            half1 = thread(mergeSortThread, std::ref(nums), beg, mid);
            mtx.unlock();
            mtx.lock();
            half2 = thread(mergeSortThread, std::ref(nums), mid + 1, end);
            mtx.unlock();

            half1.join();
            half2.join();

        } else if(*number_of_units == 1) {

            *number_of_units--;
            mtx.lock();
            half1 = thread(mergeSortThread, std::ref(nums), beg, mid);
            mtx.unlock();
            mergeSort(nums, mid + 1, end);

            half1.join();

        } else {
            mergeSort(nums, beg, mid);
            mergeSort(nums, mid + 1, end);
        }

        merge(nums, beg, mid, end);
    }
}

和标准mergeSort:

void mergeSort(vector<int> &nums, int beg, int end) {

    cout << "standard" << endl;

    int mid;

    if (beg < end) {
        mid = (beg + end) / 2;

        mergeSort(nums, beg, mid);
        mergeSort(nums, mid + 1, end);

        merge(nums, beg, mid, end);
    }
}

程序的输出(具有15个随机数和最多10个线程)是:

array: 660919 974282 721803 971892 908195 137470 226270 609453 19612 988775 652618 298558 125993 598676 489395 

new thread 10
new thread 8
new thread 6
new thread 4
new thread 2
new thread 0
standard
standard
standard
standard
standard
standard
new thread 0
standard
standard
standard
standard
new thread 0
standard
standard
new thread 0
standard
standard
new thread 0
standard
standard
new thread 0
standard
standard

sorted array: 19612 125993 137470 226270 298558 489395 598676 609453 652618 660919 721803 908195 971892 974282 988775 

问题在于计数器达到零后正在创建新线程...有人知道如何停止该线程吗?我假设这只是互斥锁的位置...

1 个答案:

答案 0 :(得分:1)

您没有将互斥锁锁定在修改或阅读*number_of_units的位置。锁定这些用法。

即使互斥锁被锁定在这些变量访问的周围,您也需要确保在读取和修改之间没有其他线程尝试读取。您可以按住锁直到两个都完成。

您还应该使用std::lock_guardstd::unique_lock而不是直接锁定互斥锁。

std::unique_lock lock(mtx);
if(*number_of_units > 1) {

    *number_of_units -= 2;
    lock.unlock();
    [...]

} else if(*number_of_units == 1) {

    *number_of_units--;
    lock.unlock();
    [...]
} else {

    lock.unlock();
    [...]
}

如果您未使用C ++ 17,则需要为std::unique_lock指定互斥锁类型,例如std::unique_lock<std::mutex>