📅  最后修改于: 2023-12-03 14:49:49.510000             🧑  作者: Mango
在C语言中,二分查找是一种高效的搜索算法。当我们需要在有序数组中查找某个数时,它的时间复杂度是O(log n)。但是,当我们的数组很大时,如果使用串行方式进行二分查找,可能会花费很长时间。这时,我们可以考虑使用多线程进行并行处理,来提高程序的效率。在本篇文章中,我们将介绍如何使用pthread库进行二分查找并行化。
首先,我们需要实现一个基本的二分查找函数。下面是一个简单的实现:
int binary_search(int *arr, int len, int target) {
int left = 0, right = len - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (target == arr[mid]) {
return mid;
} else if (target < arr[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
我们需要将任务分配到多个线程中,每个线程负责一部分数据的二分查找。我们可以使用pthread库来创建和管理线程,下面是创建线程的一个简单例子:
pthread_t threads[NUM_THREADS];
int thread_args[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
thread_args[i] = i;
int rc = pthread_create(&threads[i], NULL, func, (void *)&thread_args[i]);
if (rc) {
printf("Error: return code from pthread_create is %d\n", rc);
exit(-1);
}
}
我们需要将数据分配到线程中,让每个线程处理不同的数据。下面是将数据分配到线程中的简单例子:
for (int i = 0; i < NUM_THREADS; i++) {
data_args[i].arr = arr;
data_args[i].len = len;
data_args[i].target = target;
data_args[i].begin = i * (len / NUM_THREADS);
data_args[i].end = (i + 1) * (len / NUM_THREADS) - 1;
int rc = pthread_create(&threads[i], NULL, binary_search_thread, (void *)&data_args[i]);
if (rc) {
printf("Error: return code from pthread_create is %d\n", rc);
exit(-1);
}
}
每个线程的处理结果需要被合并,以便确认搜索结果。下面是将结果合并的简单例子:
void *binary_search_thread(void *args) {
struct thread_data *data = (struct thread_data *)args;
int *arr = data->arr;
int len = data->len;
int target = data->target;
int begin = data->begin;
int end = data->end;
int result = -1;
for (int i = begin; i <= end; i++) {
if (arr[i] == target) {
result = i;
break;
}
}
pthread_mutex_lock(&result_mutex);
if (result != -1) {
final_result = result;
}
pthread_mutex_unlock(&result_mutex);
pthread_exit(NULL);
}
下面是完整的使用pthread进行二分查找的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 4
struct thread_data {
int *arr;
int len;
int target;
int begin;
int end;
};
pthread_t threads[NUM_THREADS];
struct thread_data data_args[NUM_THREADS];
int final_result = -1;
pthread_mutex_t result_mutex;
int binary_search(int *arr, int len, int target) {
int left = 0, right = len - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (target == arr[mid]) {
return mid;
} else if (target < arr[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
void *binary_search_thread(void *args) {
struct thread_data *data = (struct thread_data *)args;
int *arr = data->arr;
int len = data->len;
int target = data->target;
int begin = data->begin;
int end = data->end;
int result = -1;
for (int i = begin; i <= end; i++) {
if (arr[i] == target) {
result = i;
break;
}
}
pthread_mutex_lock(&result_mutex);
if (result != -1) {
final_result = result;
}
pthread_mutex_unlock(&result_mutex);
pthread_exit(NULL);
}
int main() {
int arr[] = {1, 2, 3, 5, 7, 8, 11, 23, 45, 68, 99, 102, 105, 107};
int len = sizeof(arr) / sizeof(int);
int target = 68;
pthread_mutex_init(&result_mutex, NULL);
for (int i = 0; i < NUM_THREADS; i++) {
data_args[i].arr = arr;
data_args[i].len = len;
data_args[i].target = target;
data_args[i].begin = i * (len / NUM_THREADS);
data_args[i].end = (i + 1) * (len / NUM_THREADS) - 1;
int rc = pthread_create(&threads[i], NULL, binary_search_thread, (void *)&data_args[i]);
if (rc) {
printf("Error: return code from pthread_create is %d\n", rc);
exit(-1);
}
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&result_mutex);
if (final_result != -1) {
printf("The target %d is at index %d.\n", target, final_result);
} else {
printf("The target %d is not found.\n", target);
}
return 0;
}
注意,上面的代码仅供参考,具体的实现方式可能因线程数、数据分配方法等不同而有所差异。