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
| #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <pthread.h>
/** * 线程信号栈管理器 */ typedef struct { stack_t signal_stack; char *stack_buffer; pthread_t thread_id; int thread_num; } thread_stack_manager_t;
/** * 线程信号处理程序 */ void thread_signal_handler(int sig) { pthread_t current_thread = pthread_self(); printf("线程 %lu 收到信号 %d\n", (unsigned long)current_thread, sig); stack_t current_stack; if (sigaltstack(NULL, ¤t_stack) == 0) { if (current_stack.ss_flags & SS_ONSTACK) { printf(" 线程 %lu 在备用栈上处理信号\n", (unsigned long)current_thread); } else { printf(" 线程 %lu 在主栈上处理信号\n", (unsigned long)current_thread); } } printf(" 线程 %lu 信号处理完成\n", (unsigned long)current_thread); }
/** * 初始化线程栈管理器 */ int init_thread_stack_manager(thread_stack_manager_t *manager, int thread_num) { size_t stack_size = SIGSTKSZ; manager->thread_num = thread_num; manager->thread_id = pthread_self(); // 分配栈空间 manager->stack_buffer = malloc(stack_size); if (!manager->stack_buffer) { printf("线程 %d: 分配栈空间失败\n", thread_num); return -1; } // 初始化栈结构 manager->signal_stack.ss_sp = manager->stack_buffer; manager->signal_stack.ss_size = stack_size; manager->signal_stack.ss_flags = 0; printf("线程 %d: 分配备用栈 %p, 大小 %zu\n", thread_num, (void*)manager->stack_buffer, stack_size); return 0; }
/** * 线程工作函数 */ void* thread_worker(void *arg) { thread_stack_manager_t *manager = (thread_stack_manager_t*)arg; struct sigaction sa; sigset_t set; printf("工作线程 %d 启动 (ID: %lu)\n", manager->thread_num, (unsigned long)manager->thread_id); // 设置备用栈 if (sigaltstack(&manager->signal_stack, NULL) != 0) { printf("线程 %d: 设置备用栈失败: %s\n", manager->thread_num, strerror(errno)); return NULL; } printf("线程 %d: 备用栈设置成功\n", manager->thread_num); // 设置信号处理程序 memset(&sa, 0, sizeof(sa)); sa.sa_handler = thread_signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_ONSTACK; if (sigaction(SIGUSR1, &sa, NULL) != 0) { printf("线程 %d: 设置信号处理程序失败: %s\n", manager->thread_num, strerror(errno)); return NULL; } printf("线程 %d: 信号处理程序设置成功\n", manager->thread_num); // 阻塞SIGUSR1以便测试 sigemptyset(&set); sigaddset(&set, SIGUSR1); pthread_sigmask(SIG_BLOCK, &set, NULL); // 执行工作 for (int i = 0; i < 5; i++) { printf("线程 %d: 工作中... (%d/5)\n", manager->thread_num, i + 1); sleep(2); } // 解除阻塞并等待信号 printf("线程 %d: 等待信号...\n", manager->thread_num); pthread_sigmask(SIG_UNBLOCK, &set, NULL); // 等待一段时间让信号处理完成 sleep(2); printf("线程 %d: 工作完成\n", manager->thread_num); return NULL; }
/** * 演示线程安全的信号栈管理 */ int demo_thread_safe_signal_stacks() { const int num_threads = 3; pthread_t threads[num_threads]; thread_stack_manager_t managers[num_threads]; sigset_t set; printf("=== 线程安全的信号栈管理演示 ===\n"); // 阻塞SIGUSR1信号 sigemptyset(&set); sigaddset(&set, SIGUSR1); pthread_sigmask(SIG_BLOCK, &set, NULL); // 创建工作线程 printf("创建 %d 个工作线程:\n", num_threads); for (int i = 0; i < num_threads; i++) { if (init_thread_stack_manager(&managers[i], i + 1) != 0) { printf("初始化线程 %d 失败\n", i + 1); // 清理已分配的资源 for (int j = 0; j < i; j++) { free(managers[j].stack_buffer); } return -1; } if (pthread_create(&threads[i], NULL, thread_worker, &managers[i]) != 0) { printf("创建线程 %d 失败\n", i + 1); free(managers[i].stack_buffer); // 清理已分配的资源 for (int j = 0; j < i; j++) { free(managers[j].stack_buffer); } return -1; } managers[i].thread_id = threads[i]; printf("创建线程 %d: ID=%lu\n", i + 1, (unsigned long)threads[i]); } // 等待线程启动 sleep(1); // 向所有线程发送信号 printf("\n向所有线程发送SIGUSR1信号:\n"); pthread_sigmask(SIG_UNBLOCK, &set, NULL); for (int i = 0; i < num_threads; i++) { // 注意:实际应用中需要更精确的线程信号发送方法 if (kill(getpid(), SIGUSR1) == 0) { printf("向线程 %d 发送信号成功\n", i + 1); } else { printf("向线程 %d 发送信号失败: %s\n", i + 1, strerror(errno)); } sleep(1); // 间隔发送 } // 等待所有线程完成 printf("\n等待所有线程完成:\n"); for (int i = 0; i < num_threads; i++) { void *result; pthread_join(threads[i], &result); printf("线程 %d 已完成\n", i + 1); // 清理资源 free(managers[i].stack_buffer); } return 0; }
int main() { return demo_thread_safe_signal_stacks(); }
|