📅  最后修改于: 2023-12-03 15:22:15.732000             🧑  作者: Mango
二分查找是一种常见的算法,利用它可以快速地在有序数组中查找指定元素。在本文中,我们将介绍如何使用 pthread 进行二分查找。
pthread 是 POSIX 标准中线程的 API,其全称为“POSIX threads”。它提供了一些函数,允许可以在一个程序内并发运行多个并发执行线程,而这些线程共享一些数据,同时又拥有各自的私有数据。
使用 pthread 进行二分查找的过程,大致可以分为以下几个步骤:
下面是一个使用 pthread 进行二分查找的示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define THREAD_NUM 4
int array[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
int thread_result[THREAD_NUM];
pthread_mutex_t lock;
void* binarySearch(void* arg){
int* input = (int*)arg;
int left = input[0];
int right = input[1];
int target = input[2];
int thread_num = input[3];
int mid;
while (left <= right) {
mid = (left + right) / 2;
if (array[mid] == target) {
pthread_mutex_lock(&lock);
thread_result[thread_num] = mid;
pthread_mutex_unlock(&lock);
return NULL;
} else if (array[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return NULL;
}
int main(int argc, char* argv[]){
int target = atoi(argv[1]);
pthread_mutex_init(&lock, NULL);
int part_size = sizeof(array) / sizeof(int) / THREAD_NUM;
pthread_t threads[THREAD_NUM];
int inputs[THREAD_NUM][4];
for (int i = 0; i < THREAD_NUM; i++){
int left = i * part_size;
int right = (i == THREAD_NUM - 1) ? sizeof(array) / sizeof(int) - 1 : left + part_size - 1;
inputs[i][0] = left;
inputs[i][1] = right;
inputs[i][2] = target;
inputs[i][3] = i;
pthread_create(&threads[i], NULL, binarySearch, inputs[i]);
}
for (int i = 0; i < THREAD_NUM; i++) {
pthread_join(threads[i], NULL);
}
int result = -1;
for (int i = 0; i < THREAD_NUM; i++) {
if (thread_result[i] != -1) {
result = thread_result[i];
break;
}
}
if (result != -1) {
printf("Target found at index %d\n", result);
} else {
printf("Target not found\n");
}
pthread_mutex_destroy(&lock);
return 0;
}
array
,其中存储了 10 个有序的整数。int array[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
thread_result
数组,用于存储每个线程查找的结果。定义了一个 pthread_mutex_t
锁变量 lock
,用于在多个线程之间进行同步。int thread_result[THREAD_NUM];
pthread_mutex_t lock;
binarySearch
函数,用于进行二分查找。该函数需要传入一个包含 4 个整数的数组 input
,这些整数分别表示左边界、右边界、查找目标和线程编号。void* binarySearch(void* arg){
int* input = (int*)arg;
int left = input[0];
int right = input[1];
int target = input[2];
int thread_num = input[3];
int mid;
while (left <= right) {
mid = (left + right) / 2;
if (array[mid] == target) {
pthread_mutex_lock(&lock);
thread_result[thread_num] = mid;
pthread_mutex_unlock(&lock);
return NULL;
} else if (array[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return NULL;
}
在函数内部,首先从 input
中获取到左边界、右边界、查找目标和线程编号等信息,然后利用 while 循环进行二分查找。如果查找到目标元素,就使用锁将该线程的查找结果写入到 thread_result
数组中,并返回。否则,继续查找。如果没有查找到目标元素,函数返回 NULL。
main
函数内部,首先从命令行参数中获取到要查找的目标数值,并初始化锁变量。int target = atoi(argv[1]);
pthread_mutex_init(&lock, NULL);
int part_size = sizeof(array) / sizeof(int) / THREAD_NUM;
pthread_t threads[THREAD_NUM];
int inputs[THREAD_NUM][4];
for (int i = 0; i < THREAD_NUM; i++){
int left = i * part_size;
int right = (i == THREAD_NUM - 1) ? sizeof(array) / sizeof(int) - 1 : left + part_size - 1;
inputs[i][0] = left;
inputs[i][1] = right;
inputs[i][2] = target;
inputs[i][3] = i;
pthread_create(&threads[i], NULL, binarySearch, inputs[i]);
}
在这里,首先计算出每个子数组的边界,然后将这些信息填充到一个 inputs
数组中。最后,启动 THREAD_NUM
个线程,并将 inputs
数组中的内容作为参数传递给 binarySearch
函数。
main
函数中等待所有线程完成查找,并将结果合并。for (int i = 0; i < THREAD_NUM; i++) {
pthread_join(threads[i], NULL);
}
int result = -1;
for (int i = 0; i < THREAD_NUM; i++) {
if (thread_result[i] != -1) {
result = thread_result[i];
break;
}
}
if (result != -1) {
printf("Target found at index %d\n", result);
} else {
printf("Target not found\n");
}
pthread_mutex_destroy(&lock);
在这里,首先逐一等待所有线程结束,然后遍历 thread_result
数组,找到第一个不为 -1 的元素,如果找到了,则表示目标元素已经找到了,输出其下标,否则表示目标元素不存在于数组中,输出一条相关信息。最后,释放锁变量。
本文介绍了如何使用 pthread 进行二分查找。在实际应用中,可以根据实际需要对代码进行修改和优化,以达到更好的性能和效果。