98 lines
3.1 KiB
C
98 lines
3.1 KiB
C
#include <stdio.h>
|
||
#include <time.h>
|
||
#include <pthread.h>
|
||
#include <unistd.h> // For sysconf
|
||
|
||
// 随机数更新函数 (与原版相同)
|
||
void GenerateRandomNumber(unsigned int *rand1_h, unsigned int *rand1_l) {
|
||
unsigned long long x = (unsigned long long)*rand1_h;
|
||
x *= 0x6AC690C5;
|
||
x += *rand1_l;
|
||
*rand1_h = (unsigned int)x;
|
||
*rand1_l = (unsigned int)(x >> 32);
|
||
}
|
||
|
||
// 定义传递给线程的参数结构体
|
||
typedef struct {
|
||
unsigned int start;
|
||
unsigned int end;
|
||
unsigned int search_val;
|
||
} ThreadArgs;
|
||
|
||
// 全局互斥锁,只用于保护printf函数,防止输出混乱
|
||
pthread_mutex_t printf_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||
|
||
// 线程执行的函数
|
||
void* search_worker(void* args) {
|
||
ThreadArgs* t_args = (ThreadArgs*)args;
|
||
unsigned int begin_h = t_args->end;
|
||
unsigned int begin_l = t_args->start;
|
||
unsigned int search_val = t_args->search_val;
|
||
|
||
// *** 核心改动:不再提前退出,每个线程必须完成自己的任务 ***
|
||
for (unsigned int i = begin_l; i < begin_h; ++i) {
|
||
unsigned int h = i;
|
||
unsigned int l = 0x29A;
|
||
GenerateRandomNumber(&h, &l);
|
||
GenerateRandomNumber(&h, &l);
|
||
|
||
if (l == search_val) {
|
||
// 找到结果,锁住互斥锁以安全地打印
|
||
pthread_mutex_lock(&printf_mutex);
|
||
printf("找到啦~! 密码是 %08X (由线程 %lu 找到)\n", i, pthread_self());
|
||
pthread_mutex_unlock(&printf_mutex);
|
||
// *** 核心改动:不再退出,继续搜索本线程范围内的其他可能解 ***
|
||
}
|
||
}
|
||
pthread_exit(NULL);
|
||
}
|
||
|
||
int main() {
|
||
time_t begin_time, end_time;
|
||
const unsigned int search_val = 0x39A6FFBB;
|
||
|
||
// 注意:原程序的循环条件是 i < 0xFFFFFFFF,所以它本身不会测试 0xFFFFFFFF
|
||
// 为了保持行为一致,我们将总范围设为 0xFFFFFFFF
|
||
const unsigned long long total_range_end = 0xFFFFFFFF;
|
||
|
||
long num_threads = sysconf(_SC_NPROCESSORS_ONLN);
|
||
if (num_threads <= 0) {
|
||
num_threads = 4; // 默认值
|
||
}
|
||
printf("这是一个修正后的Pthreads并行搜索程序,将使用 %ld 个线程。\n", num_threads);
|
||
|
||
begin_time = time(NULL);
|
||
|
||
pthread_t threads[num_threads];
|
||
ThreadArgs thread_args[num_threads];
|
||
|
||
// 注意数据类型,防止溢出
|
||
unsigned long long chunk_size = total_range_end / num_threads;
|
||
|
||
for (long i = 0; i < num_threads; ++i) {
|
||
thread_args[i].start = i * chunk_size;
|
||
// 最后一个线程负责处理余下的所有范围
|
||
thread_args[i].end = (i == num_threads - 1) ? total_range_end : (i + 1) * chunk_size;
|
||
thread_args[i].search_val = search_val;
|
||
|
||
if (pthread_create(&threads[i], NULL, search_worker, &thread_args[i]) != 0) {
|
||
perror("Failed to create thread");
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
// 等待所有线程完成
|
||
for (long i = 0; i < num_threads; ++i) {
|
||
if (pthread_join(threads[i], NULL) != 0) {
|
||
perror("Failed to join thread");
|
||
return 2;
|
||
}
|
||
}
|
||
|
||
end_time = time(NULL);
|
||
printf("耗时 %ld 秒~~\n", end_time - begin_time);
|
||
|
||
return 0;
|
||
}
|
||
|