Files
csapp2025/threadlab/SearchRandom-pthread.c
2025-06-08 11:25:52 +08:00

98 lines
3.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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