实验要求
Write a multithreaded sorting program that works as follows: A list of integers is divided into two smaller lists of equal size. Two separate threads (which we will term sorting threads) sort each sublist using a sorting algorithm of your choice. The two sublists are then merged by a third thread—a merging thread—which merges the two sublists into a single sorted list.
Because global data are shared cross all threads, perhaps the easiest way to set up the data is to create a global array. Each sorting thread will work on one half of this array. A second global array of the same size as the unsorted integer array will also be established. The merging thread will then merge the two sublists into this second array. Graphically, this program is structured according to Figure 4.20.
This programming project will require passing parameters to each of the sorting threads. In particular, it will be necessary to identify the starting index from which each thread is to begin sorting. Refer to the instructions in Project 1 for details on passing parameters to a thread.
The parent thread will output the sorted array once all sorting threads have exited.
排序
在本次实验中,我们选择对每个线程中的数组实行快速排序的方法。
以下是快速排序的代码模块
void qsorts(int *start, int *end)
{
int nums = end - start;
if(nums > 0)
{
int index = 0;
int flag = start[0];
int i = 0, j = nums;
while(i != j)
{
while(j > i && start[j] >= flag)
--j;
start[index] = start[j];
index = j;
while(i < j && start[i] <= flag)
++i;
start[index] = start[i];
index = i;
}
start[index] = flag;
qsorts(start, start + (i - 1));
qsorts(start + j + 1, end);
}
}
void* work(void *arg) //线程排序函数
{
long index = (long)arg;
qsorts(num + index, num + index + thread_num - 1);
pthread_barrier_wait(&barrier);
pthread_exit(NULL);
}
合并排好序的数组
对其线程实现归并排序算法,将两组排列好的数组合并为一个新数组
以下为归并排序算法代码
void merge(int *data, int start, int end, int *result)
{
int left_length = (end - start + 1) / 2 + 1;
int left_index = start;
int right_index = start + left_length;
int result_index = start;
while (left_index < start + left_length && right_index < end + 1) //store data into new array
{
if (data[left_index] <= data[right_index])
{
result[result_index++] = data[left_index++];
}
else
{
result[result_index++] = data[right_index++];
}
}
while (left_index < start + left_length)
{
result[result_index++] = data[left_index++];
}
while (right_index < end + 1)
{
result[result_index++] = data[right_index++];
}
}
void merge_sort(int *data, int start, int end, int *result)
{
if (1 == end - start) //last only two elements
{
if (data[start] > data[end])
{
int temp = data[start];
data[start] = data[end];
data[end] = temp;
}
return;
}
else if (end == start)
return; //last one element then there is no need to sort;
else {
//continue to divide the interval
merge_sort(data, start, (end - start + 1) / 2 + start, result);
merge_sort(data, (end - start + 1) / 2 + start + 1, end, result);
//start to merge sorted data
merge(data, start, end, result);
for (int i = start; i <= end; ++i)
{
data[i] = result[i];
}
}
}
完整代码
以下为本实验的完整代码,其初始数组是固定在程序中的(为了满足上方的实验要求),当然也可以通过手动输入得到初始数组。
#include <pthread.h>
#include <stdio.h>
const int MAX = 19; //数组中最大数
const int n= 10
const int thread = 2; //the number of the aray
const int thread_num = 5; //the number of each thread
int num[10]={7,12,19,3,18,4,2,6,15,8};
int result[10];
pthread_barrier_t barrier;
void qsorts(int *start, int *end)
{
int nums = end - start;
if(nums > 0)
{
int index = 0;
int flag = start[0];
int i = 0, j = nums;
while(i != j)
{
while(j > i && start[j] >= flag)
--j;
start[index] = start[j];
index = j;
while(i < j && start[i] <= flag)
++i;
start[index] = start[i];
index = i;
}
start[index] = flag;
qsorts(start, start + (i - 1));
qsorts(start + j + 1, end);
}
}
void* work(void *arg) //线程排序函数
{
long index = (long)arg;
qsorts(num + index, num + index + thread_num - 1);
pthread_barrier_wait(&barrier);
pthread_exit(NULL);
}
void merge(int *data, int start, int end, int *result)
{
int left_length = (end - start + 1) / 2 + 1;
int left_index = start;
int right_index = start + left_length;
int result_index = start;
while (left_index < start + left_length && right_index < end + 1) //store data into new array
{
if (data[left_index] <= data[right_index])
{
result[result_index++] = data[left_index++];
}
else
{
result[result_index++] = data[right_index++];
}
}
while (left_index < start + left_length)
{
result[result_index++] = data[left_index++];
}
while (right_index < end + 1)
{
result[result_index++] = data[right_index++];
}
}
void merge_sort(int *data, int start, int end, int *result)
{
if (1 == end - start) //last only two elements
{
if (data[start] > data[end])
{
int temp = data[start];
data[start] = data[end];
data[end] = temp;
}
return;
}
else if (end == start)
return; //last one element then there is no need to sort;
else {
//continue to divide the interval
merge_sort(data, start, (end - start + 1) / 2 + start, result);
merge_sort(data, (end - start + 1) / 2 + start + 1, end, result);
//start to merge sorted data
merge(data, start, end, result);
for (int i = start; i <= end; ++i)
{
data[i] = result[i];
}
}
}
int main()
{
int i;
pthread_t ptid;
gettimeofday(&start, NULL);
pthread_barrier_init(&barrier, NULL, thread + 1);
for (int i = 0; i < thread; ++i){
pthread_create(&ptid, NULL, work, (void *)(i * thread_num));
}
pthread_barrier_wait(&barrier);
merge_sort(num,0,9,result);
printf("The ordered array is :\n");
for (i = 0; i < n; ++i){
printf("%d\n", result[i]);
}
return 0;
}
实验结果
编译 .c 文件
执行文件 thread
Tips : 本实验需在Linux编译环境下实现。
Pthread library is not the acquiescent library in the Linux system . It needs to use static library , libpthread.a . Then we would add the ‘-lpthread’ parameter when compiling the file .Furthermore , name the file as ‘thread’.