多线程的同步,首先呢我觉得多线程很重要的一个就是线程间通信,线程间需要一个临界数据(这个数据放在所有线程都能看到的地方,全局段或者堆上),大家有信息都放这个里面你需要你就来拿数据,那问题就来了。这个线程正在写,但是这个时候有一个不长眼的线程来取数据。或者我还没取到临界数据基于有一个混蛋把数据改了那这个县城肯定拿不到数据了。
那么为了防止这种现象,我们引入了互斥,就是说这个线程我正在用就置一,其他线程看见我置一了就不能用了(先等着吧,就是阻塞)。这样保证了一个线程写的时候不会有人打扰就是线程互斥的唯一性和排他性。注意哦这个上锁是原子操作!谁也不能打断耶稣来了也不行!
接下来解决下一个问题:一个线程还没写进去数据,另一个线程就去读数据了,那么肯定这个线程读不到正确的数据。为了解决这个问题我们引入了同步。啥叫同步呢就是一个顺序,我先来写,你再来读。咱俩的数据就一样了,咱俩这个就叫同步。就很清晰!
那同步怎么实现呢?不要急不要慌!
同步的过程大概就是一个线程先写数据,写的过程中不能有任何人来打扰。写完了去告诉另一个线程我写完了你不用等啦,来取数据吧。这样两个线程的通信就完成了。就完成了同步。思路大概就是这样啦。
接下来想一下怎么实现呢?首先得用互斥量(说实话这个玩意就一个原子性的全局标志位),在一个线程(也就是我)写的时候去上锁,这个时候这个临界数据就被我单独占有了,别人没法访问,保证了唯一性也保护了我的数据。等我写完了,把锁解开,这个时候别人才这能用这个临界数据。(怎么觉得这么像上厕所,各位看官老爷想一下,我去厕所,把门锁上就上锁了。这个厕所被我占用,别人进不来。我上完厕所,我把锁解开我离开厕所别人就能用啦!当然没有任何数据留下!注意卫生,哈哈哈哈哈哈。就很像对吧!)。这样就完成了第一步互斥(上锁)。
之后我写完了数据得告诉别人来读取数据了!就要用到又一个工具:条件变量!这个条件变量就俩作用:挂起一个不满足条件的线程让这个线程进入休眠。等到条件满足时唤醒满足条件的线程。这样一来通知其他线程也完成了!
这个是大概说了一下条件变量和互斥锁完成同步的思路。当然还可以直接用信号量去完成同步。信号量就很直接了大于0就获取临界变量。小于0就进入阻塞态,等待一个线程释放信号量,在释放信号量的同时也会唤醒等待信号量的线程!用信号量就是更复杂一下,这里说的复杂不是代码复杂而是算法更加复杂些,互斥锁和条件变量就更简单些。其实从根本上看这些东西都只是一些全局的原子操作!