一个例子让你看清线程调度的随机性( 二 )


value1 = count; value2 = count;时序图如下:
一个例子让你看清线程调度的随机性文章插图
如上图所示:

  1. 时刻n , 主线程获得mutex , 从而进入临界区;
  2. 时刻n+1 , 时间片到了 , 切换到子线程;
  3. n+2时刻子线程申请不到锁mutex , 所以放弃cpu , 进入休眠;
  4. n+3时刻 , 主线程释放mutex , 离开临界区 , 并唤醒阻塞在mutex的子线程 , 子线程申请到mutex , 进入临界区;
  5. n+4时刻 , 子线程离开临界区 , 释放mutex 。
可以看到 , 加锁之后 , 即使主线程在value2 =count; 之前产生了调度 , 子线程由于获取不到mutex , 会进入休眠 , 只有主线程出了临界区 , 子线程才能获得mutex , 访问value1和value2,就永远不会打印信息 , 就实现了我们预期的代码时序 。
总结实际项目中 , 可能程序的并发的情况可能会更加复杂 , 比如多个cpu上运行的任务之间 , cpu运行的任务和中断之间 , 中断和中断之间 , 都有可能并发 。
有些调度的概率虽然很小 , 但是不代表不发生 , 而且由于资源同步互斥导致的问题 , 很难复现 , 纵观Linux内核代码 , 所有的临界资源都会对应锁 。
多阅读Linux内核源码 , 学向大神学习 , 与大神神交 。正所谓代码读百遍 , 其义自见! 熟读代码千万行 , 不会编写也会抄!
关于内核和应用程序的同步互斥的知识点 , 可以查看一口君的其他文章 。
【一个例子让你看清线程调度的随机性】更多Linux干货 , 请关注一口Linux