📜  使用pthread进行二进制搜索(1)

📅  最后修改于: 2023-12-03 14:49:49.510000             🧑  作者: Mango

使用pthread进行二进制搜索

在C语言中,二分查找是一种高效的搜索算法。当我们需要在有序数组中查找某个数时,它的时间复杂度是O(log n)。但是,当我们的数组很大时,如果使用串行方式进行二分查找,可能会花费很长时间。这时,我们可以考虑使用多线程进行并行处理,来提高程序的效率。在本篇文章中,我们将介绍如何使用pthread库进行二分查找并行化。

1. 实现串行二分查找

首先,我们需要实现一个基本的二分查找函数。下面是一个简单的实现:

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;
}
2. 使用pthread进行并行化
2.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);
    }
}
2.2 分配任务

我们需要将数据分配到线程中,让每个线程处理不同的数据。下面是将数据分配到线程中的简单例子:

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);
    }
}
2.3 合并结果

每个线程的处理结果需要被合并,以便确认搜索结果。下面是将结果合并的简单例子:

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);
}
3. 完整代码

下面是完整的使用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;
}

注意,上面的代码仅供参考,具体的实现方式可能因线程数、数据分配方法等不同而有所差异。