DragonOS/user/apps/c_unitest/test_pthread_basic.c

149 lines
5.4 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 <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
// 定义要创建的子线程数量
#define NUM_THREADS 50
// 全局共享变量
static int shared_counter = 0;
static pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
// 全局健壮锁,用于测试 robust mutex
static pthread_mutex_t robust_mutex;
// 子线程函数
void *thread_function(void *arg) {
int thread_id = *(int *)arg;
printf("[Thread %d] 子线程开始运行\n", thread_id);
printf("[Thread %d] 子线程 ID: %lu, PID: %d\n", thread_id, pthread_self(), getpid());
// 测试普通互斥锁 - 触发 futex
printf("[Thread %d] 尝试获取普通互斥锁...\n", thread_id);
pthread_mutex_lock(&counter_mutex);
printf("[Thread %d] 获取普通互斥锁成功,进入临界区\n", thread_id);
// 临界区操作
int old_value = shared_counter;
// usleep(100000); // 延长临界区时间,增加竞争
shared_counter++;
printf("[Thread %d] 共享计数器: %d -> %d\n", thread_id, old_value, shared_counter);
pthread_mutex_unlock(&counter_mutex);
printf("[Thread %d] 释放普通互斥锁\n", thread_id);
// 测试健壮锁 - 可以处理持有者异常退出的情况
printf("[Thread %d] 尝试获取健壮锁...\n", thread_id);
int ret = pthread_mutex_lock(&robust_mutex);
if (ret == 0) {
printf("[Thread %d] 获取健壮锁成功\n", thread_id);
// 模拟一些工作
// usleep(50000);
pthread_mutex_unlock(&robust_mutex);
printf("[Thread %d] 释放健壮锁\n", thread_id);
} else if (ret == EOWNERDEAD) {
printf("[Thread %d] 检测到健壮锁持有者已死亡,尝试恢复\n", thread_id);
pthread_mutex_consistent(&robust_mutex);
pthread_mutex_unlock(&robust_mutex);
printf("[Thread %d] 健壮锁已恢复并释放\n", thread_id);
} else {
printf("[Thread %d] 获取健壮锁失败,错误码: %d\n", thread_id, ret);
}
// 模拟一些工作
printf("[Thread %d] 正在执行工作...\n", thread_id);
// sleep(2);
printf("[Thread %d] 工作完成,准备退出\n", thread_id);
// 返回值
int *result = malloc(sizeof(int));
*result = thread_id * 100;
printf("[Thread %d] 子线程退出,返回值: %d\n", thread_id, *result);
// 直接返回,效果与 pthread_exit(result) 相同
return result;
}
int main() {
pthread_t threads[NUM_THREADS];
int thread_args[NUM_THREADS];
int ret;
void *thread_result;
pthread_mutexattr_t attr;
printf("=== pthread_create 和 pthread_join 测试程序 ===\n");
printf("[Main] 主线程开始,线程 ID: %lu\n", pthread_self());
// 初始化健壮锁
printf("[Main] 初始化健壮锁...\n");
pthread_mutexattr_init(&attr);
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
ret = pthread_mutex_init(&robust_mutex, &attr);
if (ret != 0) {
printf("[Main] 错误: 健壮锁初始化失败,返回值 = %d\n", ret);
return 1;
}
pthread_mutexattr_destroy(&attr);
printf("[Main] 健壮锁初始化成功\n");
printf("[Main] 准备创建 %d 个子线程\n", NUM_THREADS);
// 创建多个子线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_args[i] = i + 1;
printf("[Main] 正在创建子线程 %d...\n", thread_args[i]);
ret = pthread_create(&threads[i], NULL, thread_function, &thread_args[i]);
if (ret != 0) {
printf("[Main] 错误: pthread_create 失败,线程 %d返回值 = %d\n", i + 1, ret);
return 1;
}
printf("[Main] 子线程 %d 创建成功,线程句柄: %lu\n", thread_args[i], threads[i]);
}
printf("[Main] 所有子线程创建完成\n");
printf("[Main] 主线程继续执行自己的工作...\n");
// 主线程也做一些工作
// !!!!看这里只要开启sleep的话等待所有子线程都返回了再join,就不会报错 can not find nearest vma
// sleep(1);
printf("[Main] 主线程工作完成,等待所有子线程结束...\n");
// 等待所有子线程结束
for (int i = 0; i < NUM_THREADS; i++) {
printf("[Main] 调用 pthread_join 等待子线程 %d...\n", thread_args[i]);
ret = pthread_join(threads[i], &thread_result);
if (ret != 0) {
printf("[Main] 错误: pthread_join 失败,线程 %d返回值 = %d\n", thread_args[i], ret);
return 1;
}
printf("[Main] 子线程 %d pthread_join 成功返回\n", thread_args[i]);
if (thread_result != NULL) {
int result_value = *(int *)thread_result;
printf("[Main] 子线程 %d 返回值: %d\n", thread_args[i], result_value);
free(thread_result);
} else {
printf("[Main] 子线程 %d 返回值为 NULL\n", thread_args[i]);
}
}
printf("[Main] 所有线程已结束,程序退出\n");
printf("[Main] 最终共享计数器值: %d (期望值: %d)\n", shared_counter, NUM_THREADS);
// 清理资源
pthread_mutex_destroy(&counter_mutex);
pthread_mutex_destroy(&robust_mutex);
printf("[Main] 互斥锁已销毁\n");
printf("=== 测试完成 ===\n");
return 0;
}