オペレーティングシステムプログラミングプロジェクト5マルチスレッドシーケンス

実験要件

次のように機能するマルチスレッドソートプログラムを作成します。整数のリストは、同じサイズの2つの小さなリストに分割されます。2つの別々のスレッド(これをソートスレッドと呼びます)は、選択したソートアルゴリズムを使用して各サブリストをソートします。次に、2つのサブリストは、2つのサブリストを単一のソート済みリストにマージする3番目のスレッド(マージスレッド)によってマージされます。

グローバルデータはすべてのスレッドで共有されるため、データを設定する最も簡単な方法は、グローバル配列を作成することです。各ソートスレッドは、この配列の半分で機能します。ソートされていない整数配列と同じサイズの2番目のグローバル配列も確立されます。次に、マージスレッドは、2つのサブリストをこの2番目の配列にマージします。グラフィカルに、このプログラムは図4.20に従って構成されています。

ここに画像の説明を挿入

このプログラミングプロジェクトでは、各並べ替えスレッドにパラメータを渡す必要があります。特に、各スレッドがソートを開始する開始インデックスを特定する必要があります。スレッドへのパラメーターの受け渡しの詳細については、プロジェクト1の手順を参照してください。

すべてのソートスレッドが終了すると、親スレッドはソートされた配列を出力します。

ソート

この実験では、各スレッドで配列を高速に並べ替える方法を選択します。
以下はクイックソートのコードモジュールです

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);
}

ソートされた配列をマージする

スレッドにマージソートアルゴリズムを実装し、2つの配列を新しい配列にマージします

以下は、マージソートアルゴリズムのコードです

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ファイルをコンパイルします
ここに画像の説明を挿入

ファイルスレッドを実行する

ヒント:本を验ダウンロード在Linux编译環状態下で
。PthreadライブラリはLinuxシステムの黙認ライブラリではありません。静的ライブラリlibpthread.aを使用する必要があります。次に、ファイルをコンパイルするときに「-lpthread」パラメータを追加します。さらに、ファイルに「thread」という名前を付けます。

おすすめ

転載: blog.csdn.net/taotaotao11/article/details/112980424