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; 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)); 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)); } 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, .crash_probability = 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(); }
|