我正在用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 回答
您没有锁定修改或读取
*number_of_units
点周围的互斥锁 . 把锁放在这些用法周围 .即使互斥锁被锁定在这些变量访问周围,您也需要确保在读取和修改之间没有其他线程尝试读取 . 您可以通过按住锁直到两者都完成为止 .
您还应该使用
std::lock_guard
或std::unique_lock
而不是直接锁定互斥锁 .如果您不使用C 17,则需要为
std::unique_lock
指定互斥锁类型,例如std::unique_lock<std::mutex>
.