一种线程同步共享链表的方式----waitlist

本文探讨了线程同步中使用信号量和锁时遇到的问题,并通过一个具体案例——打印配置信息时可能发生的异常来说明。当一个线程遍历链表过程中放权给其他线程时,若后者删除当前节点,则可能导致前者的指针悬空。

线程同步中遇到的一类问题

线程中同步共享链表方式一般有信号量和锁,但是有些场景单纯的使用 信号量和锁,不能满足特定场景的需求。

比如:打印配置信息,当现实的内容比较多的时候,需要放权出去,这个时候,会有别的任务(这里的任务是指的一个线程 )去删除打印的节点,很可能就会异常。

thread A 遍历链表: 1—> 2—> 3—> 4—> 5—> 6—> NULL ,在遍历完2,开始遍历3处放权。
thread B delete 3

如果某一时刻调度按照 threadA –> threadB–> threadA 的方式调度,就会出现访问空指针的异常。

异常场景模拟代码

详细代码见github

### Mutex Wait List 初始化对多进程锁竞争的影响 #### 1. Mutex 的内部结构概述 Mutex 内部维护了一个等待队列(Wait List),用于记录那些因为无法立即获取锁而被挂起的线程或进程。当一个线程试图锁定已经被占用的 Mutex 时,它会被加入到这个等待队列中,并进入休眠状态。一旦当前持有锁的线程释放了锁,系统会从等待队列中唤醒下一个合适的候选者[^5]。 #### 2. Wait List 的初始化方式及其影响因素 Wait List 的初始化策略直接影响到了后续锁竞争的表现形式以及公平性等问题。常见的两种初始化方法分别为 FIFO (先进先出)模式与随机选取模式: - **FIFO 模式的初始化** 如果 Mutex 的 Wait List 被设计成按照请求顺序排列的新成员列表,则每次只有一个最早到达的线程能够优先获得资源使用权。这种做法虽然简单直观,但却容易造成所谓的“雷鸣效应”——即大量处于睡眠中的线程几乎同时醒来争夺同一个锁实例,进而导致严重的 CPU 时间浪费现象发生[^6]。 - **随机选取模式的初始化** 另外一种思路则是打破严格的先后次序关系,在多个符合条件的竞争者之间随机挑选一位幸运儿作为新主人。这样的安排有助于缓解某些特定情况下可能出现的大规模同步风暴问题;然而与此同时也会牺牲掉部分程序运行轨迹可预测性的优点[^7]。 无论采取哪种具体的实现手段,都需要考虑到以下几点潜在风险: - **死锁可能性增加**:不当设置可能会使得原本独立运作的不同子模块间形成循环依赖链条; - **饥饿状况加剧**:长期得不到服务机会的小概率事件参与者面临越来越渺茫的成功几率; - **额外开销累积**:频繁调整复杂的数据结构本身也需要消耗一定数量级的时间成本。 #### 3. 多进程环境下特殊挑战 对于跨进程共享同一把 Mutex 场景而言,由于涉及到内存映射文件或者信号量之类的外部媒介传递消息,所以整体流程变得更加繁琐耗时。此时如何合理规划初始参数配置显得尤为重要。例如可以通过预先分配固定大小缓冲区来容纳预期范围内的最大并发数限制,从而有效降低动态扩展带来的不确定性干扰[^8]。 ```c #include <pthread.h> pthread_mutex_t mutex; void init_mutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); // 设置为错误检查类型以增强调试能力 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); pthread_mutex_init(&mutex, &attr); } // 销毁之前记得清理属性对象 void destroy_mutex() { pthread_mutex_destroy(&mutex); pthread_mutexattr_destroy(); } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值