1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
| #include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> #include <time.h>
/** * 健壮性测试配置 */ typedef struct { int num_threads; int test_duration; int crash_probability; // 0-100,表示异常终止概率 int use_robust_mutex; } robustness_test_config_t;
/** * 测试统计信息 */ typedef struct { atomic_int lock_attempts; atomic_int lock_success; atomic_int lock_failures; atomic_int owner_dead_detected; atomic_int consistency_restored; atomic_int normal_terminations; atomic_int abnormal_terminations; } test_stats_t;
/** * 测试线程数据 */ typedef struct { int thread_id; pthread_mutex_t *mutex; test_stats_t *stats; robustness_test_config_t *config; volatile int *terminate_flag; } test_thread_data_t;
/** * 初始化健壮互斥锁 */ int init_test_mutex(pthread_mutex_t *mutex, int robust) { pthread_mutexattr_t attr; int result; result = pthread_mutexattr_init(&attr); if (result != 0) return result; if (robust) { result = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); if (result != 0) { pthread_mutexattr_destroy(&attr); return result; } } result = pthread_mutex_init(mutex, &attr); pthread_mutexattr_destroy(&attr); return result; }
/** * 测试线程函数 */ void* test_thread(void *arg) { test_thread_data_t *data = (test_thread_data_t*)arg; int result; printf("测试线程 %d 启动\n", data->thread_id); srand(time(NULL) + data->thread_id); while (!(*data->terminate_flag)) { // 尝试获取互斥锁 atomic_fetch_add(&data->stats->lock_attempts, 1); result = pthread_mutex_lock(data->mutex); if (result == 0) { atomic_fetch_add(&data->stats->lock_success, 1); // 模拟持有锁的工作 usleep(10000 + (rand() % 50000)); // 10-60ms // 随机决定是否异常终止(模拟崩溃) if (data->config->crash_probability > 0 && rand() % 100 < data->config->crash_probability) { printf("线程 %d: 模拟异常终止\n", data->thread_id); atomic_fetch_add(&data->stats->abnormal_terminations, 1); exit(1); // 模拟崩溃,不释放锁 } // 正常释放锁 pthread_mutex_unlock(data->mutex); atomic_fetch_add(&data->stats->normal_terminations, 1); } else if (result == EOWNERDEAD) { atomic_fetch_add(&data->stats->owner_dead_detected, 1); printf("线程 %d: 检测到锁持有者异常终止\n", data->thread_id); // 恢复一致性 result = pthread_mutex_consistent(data->mutex); if (result == 0) { atomic_fetch_add(&data->stats->consistency_restored, 1); printf("线程 %d: 成功恢复锁一致性\n", data->thread_id); pthread_mutex_unlock(data->mutex); } else { atomic_fetch_add(&data->stats->lock_failures, 1); printf("线程 %d: 恢复一致性失败: %s\n", data->thread_id, strerror(result)); } } else { atomic_fetch_add(&data->stats->lock_failures, 1); printf("线程 %d: 获取锁失败: %s\n", data->thread_id, strerror(result)); } // 短暂休息 usleep(10000 + (rand() % 20000)); // 10-30ms } printf("测试线程 %d 结束\n", data->thread_id); return NULL; }
/** * 显示测试统计 */ void show_test_statistics(test_stats_t *stats) { printf("\n=== 测试统计结果 ===\n"); printf("锁尝试次数: %d\n", atomic_load(&stats->lock_attempts)); printf("成功获取锁: %d\n", atomic_load(&stats->lock_success)); printf("获取锁失败: %d\n", atomic_load(&stats->lock_failures)); printf("检测到异常终止: %d\n", atomic_load(&stats->owner_dead_detected)); printf("恢复一致性: %d\n", atomic_load(&stats->consistency_restored)); printf("正常终止: %d\n", atomic_load(&stats->normal_terminations)); printf("异常终止: %d\n", atomic_load(&stats->abnormal_terminations)); if (atomic_load(&stats->lock_attempts) > 0) { double success_rate = (double)atomic_load(&stats->lock_success) / atomic_load(&stats->lock_attempts) * 100; printf("锁获取成功率: %.2f%%\n", success_rate); } }
/** * 演示健壮性测试 */ int demo_robustness_testing() { pthread_mutex_t mutex; pthread_t *threads; test_thread_data_t *thread_data; test_stats_t stats = {0}; volatile int terminate_flag = 0; robustness_test_config_t config = { .num_threads = 5, .test_duration = 30, // 30秒 .crash_probability = 5, // 5%概率异常终止 .use_robust_mutex = 1 }; printf("=== 健壮性测试工具 ===\n"); printf("测试配置:\n"); printf(" 线程数: %d\n", config.num_threads); printf(" 测试时长: %d 秒\n", config.test_duration); printf(" 异常终止概率: %d%%\n", config.crash_probability); printf(" 使用健壮互斥锁: %s\n", config.use_robust_mutex ? "是" : "否"); // 初始化互斥锁 if (init_test_mutex(&mutex, config.use_robust_mutex) != 0) { printf("初始化互斥锁失败\n"); return -1; } // 分配线程数组 threads = malloc(config.num_threads * sizeof(pthread_t)); thread_data = malloc(config.num_threads * sizeof(test_thread_data_t)); if (!threads || !thread_data) { printf("分配内存失败\n"); pthread_mutex_destroy(&mutex); free(threads); free(thread_data); return -1; } // 创建测试线程 printf("创建 %d 个测试线程...\n", config.num_threads); for (int i = 0; i < config.num_threads; i++) { thread_data[i].thread_id = i + 1; thread_data[i].mutex = &mutex; thread_data[i].stats = &stats; thread_data[i].config = &config; thread_data[i].terminate_flag = &terminate_flag; int result = pthread_create(&threads[i], NULL, test_thread, &thread_data[i]); if (result != 0) { printf("创建线程 %d 失败: %s\n", i + 1, strerror(result)); // 清理已创建的线程 terminate_flag = 1; for (int j = 0; j < i; j++) { pthread_join(threads[j], NULL); } pthread_mutex_destroy(&mutex); free(threads); free(thread_data); return -1; } } // 运行测试 printf("开始测试,持续 %d 秒...\n", config.test_duration); sleep(config.test_duration); // 停止测试 printf("停止测试...\n"); terminate_flag = 1; // 等待所有线程结束 for (int i = 0; i < config.num_threads; i++) { pthread_join(threads[i], NULL); } // 显示统计结果 show_test_statistics(&stats); // 清理资源 pthread_mutex_destroy(&mutex); free(threads); free(thread_data); return 0; }
int main() { return demo_robustness_testing(); }
|