微网站平台奉贤注册公司
2026/1/16 17:50:45 网站建设 项目流程
微网站平台,奉贤注册公司,网站建设手机端页面模板,金石项目管理软件多线程并发编程笔记#xff1a;线程竞争资源模型一、代码示例对比分析示例1#xff1a;带线程ID的窗口竞争模型#include stdio.h #include pthread.h #include stdlib.h #include unistd.h #include time.hint win 3; // 可用窗口…多线程并发编程笔记线程竞争资源模型一、代码示例对比分析示例1带线程ID的窗口竞争模型#include stdio.h #include pthread.h #include stdlib.h #include unistd.h #include time.h int win 3; // 可用窗口数 pthread_mutex_t mutex; void *th(void *arg) { int id *(int *)arg; // 获取线程ID sleep(rand() % 5); // 随机延迟0-4秒 while (1) // 持续尝试直到成功 { pthread_mutex_lock(mutex); if(win 0) // 检查是否有可用窗口 { win--; // 占用一个窗口 pthread_mutex_unlock(mutex); printf(%d:get win\n, id); // 显示获取成功 sleep(rand() % 3 1); // 模拟使用窗口1-3秒 pthread_mutex_lock(mutex); win; // 释放窗口 pthread_mutex_unlock(mutex); printf(%d:relese win\n, id); // 显示释放 break; // 退出循环 } else { printf(%d: 没有可用窗口等待...\n, id); pthread_mutex_unlock(mutex); sleep(1); // 等待1秒后重试 } } return NULL; } int main(int argc, char **argv) { srand(time(NULL)); // 初始化随机种子 pthread_t tid[10]; // 线程ID数组 int id[10]; // 线程编号数组 // 初始化线程编号 for (int i 0; i 10; i) { id[i] i 1; } pthread_mutex_init(mutex, NULL); // 初始化互斥锁 // 创建10个线程 for (int i 0; i 10; i) { pthread_create(tid[i], NULL, th, id[i]); } // 等待所有线程结束 for (int i 0; i 10; i) { pthread_join(tid[i], NULL); } pthread_mutex_destroy(mutex); // 销毁互斥锁 return 0; }示例2匿名线程竞争模型#include pthread.h #include stdio.h #include stdlib.h #include string.h #include time.h #include unistd.h int win 3; // 可用窗口数 pthread_mutex_t mutex; void* th(void* arg) { while (1) { pthread_mutex_lock(mutex); if (win 0) // 检查是否有可用窗口 { win--; // 占用窗口 pthread_mutex_unlock(mutex); printf(get win...\n); // 获取成功 sleep(rand() % 5 1); // 使用窗口1-5秒 pthread_mutex_lock(mutex); win; // 释放窗口 printf(relese win...\n); pthread_mutex_unlock(mutex); break; // 完成任务 } else { pthread_mutex_unlock(mutex); // 这里没有等待逻辑会快速重试 } } return NULL; } int main(int argc, char** argv) { int i 0; srand(time(NULL)); // 初始化随机种子 pthread_t tid[10] {0}; // 线程ID数组 pthread_mutex_init(mutex, NULL); // 初始化互斥锁 // 创建10个线程 for (i 0; i 10; i) { pthread_create(tid[i], NULL, th, NULL); // 不传递参数 } // 等待所有线程结束 for (i 0; i 10; i) { pthread_join(tid[i], NULL); } pthread_mutex_destroy(mutex); // 销毁互斥锁 return 0; }示例3多互斥锁竞争模型trylock实现#include pthread.h #include stdio.h #include stdlib.h #include string.h #include time.h #include unistd.h pthread_mutex_t mutex1; // 窗口1的锁 pthread_mutex_t mutex2; // 窗口2的锁 pthread_mutex_t mutex3; // 窗口3的锁 void* th(void* arg) { int ret 0; while (1) { // 尝试获取窗口1 ret pthread_mutex_trylock(mutex1); if (0 ret) { printf(get win1...\n); sleep(rand() % 5 1); printf(release win1...\n); pthread_mutex_unlock(mutex1); break; } else { // 尝试获取窗口2 ret pthread_mutex_trylock(mutex2); if (0 ret) { printf(get win2...\n); sleep(rand() % 5 1); printf(release win2...\n); pthread_mutex_unlock(mutex2); break; } else { // 尝试获取窗口3 ret pthread_mutex_trylock(mutex3); if (0 ret) { printf(get win3...\n); sleep(rand() % 5 1); printf(release win3...\n); pthread_mutex_unlock(mutex3); break; } else { // 所有窗口都忙可以添加等待逻辑 // 当前版本会忙等待 } } } } return NULL; } int main(int argc, char** argv) { int i 0; srand(time(NULL)); pthread_t tid[10] {0}; pthread_mutex_init(mutex1, NULL); pthread_mutex_init(mutex2, NULL); pthread_mutex_init(mutex3, NULL); for (i 0; i 10; i) { pthread_create(tid[i], NULL, th, NULL); } for (i 0; i 10; i) { pthread_join(tid[i], NULL); } pthread_mutex_destroy(mutex1); pthread_mutex_destroy(mutex2); pthread_mutex_destroy(mutex3); return 0; }二、三种模型对比分析1.设计思路对比模型核心思想资源表示竞争方式模型1集中式管理计数器(win)所有线程竞争一个锁检查计数器模型2简化集中式计数器(win)同上但无线程ID和等待消息模型3分布式管理三个独立锁每个窗口独立锁trylock轮询2.实现复杂度对比模型锁数量代码复杂度灵活性模型11个互斥锁中等窗口数量易扩展模型21个互斥锁简单功能最简模型33个互斥锁较高每个窗口独立控制3.性能特点对比模型锁竞争公平性并发度模型1高一个锁FIFO近似公平低模型2高一个锁不确定低模型3低三个锁优先抢占高三、关键技术点详解1.pthread_mutex_trylock 使用int ret pthread_mutex_trylock(mutex); // 返回值 // 0: 成功获取锁 // EBUSY: 锁已被占用 // 其他: 错误2.锁的初始化与销毁// 初始化 pthread_mutex_init(mutex, NULL); // 或静态初始化 pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER; // 销毁 pthread_mutex_destroy(mutex);3.线程创建与等待// 创建线程 pthread_create(tid[i], NULL, thread_func, arg); // 等待线程结束 pthread_join(tid[i], NULL);四、问题与改进1.问题示例1.2问题Q1: 为什么线程执行顺序不确定操作系统线程调度具有随机性sleep(rand() % 5)引入随机延迟锁竞争结果不确定Q2: 如何保证线程安全使用互斥锁保护所有共享资源访问确保加锁和解锁配对出现避免在临界区内进行耗时操作Q3: 为什么需要pthread_join等待线程完成防止主线程提前退出回收线程资源确保所有任务完成Q4: 如何优化性能减少临界区内的操作使用读写锁如果适用考虑无锁数据结构示例3的问题忙等待问题所有窗口都忙时线程会快速轮询消耗CPU饥饿问题可能某些线程永远抢不到窗口优先级固定总是先尝试窗口1然后是2、32.改进方案// 改进版添加随机等待和公平性 void* th_improved(void* arg) { int ret 0; int try_count 0; while (1) { // 随机选择尝试顺序提高公平性 int order[3] {0, 1, 2}; shuffle(order, 3); // 随机打乱顺序 for (int i 0; i 3; i) { pthread_mutex_t* mutexes[3] {mutex1, mutex2, mutex3}; ret pthread_mutex_trylock(mutexes[order[i]]); if (0 ret) { printf(get win%d...\n, order[i]1); sleep(rand() % 5 1); printf(release win%d...\n, order[i]1); pthread_mutex_unlock(mutexes[order[i]]); return NULL; } } // 所有窗口都忙指数退避等待 try_count; int wait_time (1 try_count); // 指数增长 if (wait_time 8) wait_time 8; printf(all windows busy, waiting %d seconds...\n, wait_time); sleep(wait_time); } return NULL; }五、应用场景建议1.使用模型1计数器的场景资源完全同质化需要精确控制资源总数扩展性要求高窗口数量可能变化2.使用模型2简化版的场景快速原型开发调试和演示资源竞争不激烈3.使用模型3多锁的场景资源有差异如不同服务窗口需要高并发性能可以接受一定的不公平性六、最佳实践总结根据需求选模型同质资源 → 计数器模型异质资源 → 多锁模型简单场景 → 简化模型避免忙等待trylock失败后适当sleep使用指数退避策略考虑使用条件变量确保资源释放每个lock都要有对应的unlock所有退出路径都要释放锁主线程等待所有子线程错误处理检查pthread函数返回值添加适当的日志输出考虑线程安全的错误处理性能优化减少临界区大小避免在锁内进行IO操作根据竞争程度调整策略七、扩展思考信号量替代方案可以使用信号量semaphore更简洁地实现资源计数条件变量使用条件变量避免忙等待节省CPU资源线程池对于频繁创建销毁的场景考虑使用线程池这个模型是多线程编程的基础模式广泛应用于数据库连接池网络服务器连接管理生产者消费者问题资源池管理等场景

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询