并发与事务

本博客只是在开发过程中,对遇到的多线程问题的思考,如何在保证数据正确的前提下,提高性能。

我觉得并发要考虑两个问题:

  1. 在IO层次,并发链接数过多
    1. 例如C10K,C10M的问题,是通过reactor'模式解决?例如开源的网络库都是使用单线程IO复用+非阻塞的思想解决,最优!还是通过一个连接对应一个线程,或者是说线程池解决。
    2. 通常来说,IO复用解决IO问题,线程池+阻塞队列解决计算密集型的问题
  2. 多线程,多进程的并发问题,并发读写怎么解决?数据如何可以不脏不乱?
    1. 并发问题可以通过mvcc(多版本,写时复制),锁,条件变量等机制来解决。一般来说,多线程并发问题用锁来解决。
    2. 并发读写最好就从架构上解决问题,达到无锁。如果有锁,那么线程挂起,线程切换是有开销的,可以锁住之后,其他进程就要等待,这并发度可想而知。
    3. 解决:例如一个线程只操作一个划分的子区域,一个逻辑队列等。
    4. 可以用单线程解决就不要用多线程,可以无锁解决就不要加锁。例如redis用单线程解决了线程切换,数据并发冲突问题,hash解决数据一致性问题,主从同步解决可靠性问题。

问题

如何保证一个操作的完整性呢,例如一个写着在写,一个读者读,怎么办?

解决

设一个写入标志位,只有写入成功,读者才可以读,否则阻塞,或者返回空。这样当读者可以读数据的时候,读到的都是完整的数据,但是2个写者如果同时写数据,还是有冲突,因此一段区域不能有2个写者。

问题

如果一个读者在读,如果一个写着准备将数据删除呢?

解决1

设一个删除标志位,读者读完检查删除标志位,如果删除标志位至为1,则返回空(或者事物回滚),否则返回读到的内容。

解决2

写者先将删除标志位设为1,等待一段时间(如果设为标志位之前有读者在读,应该读完毕的时间),然后删除数据(或者最后由回收进程删除数据),如果多个写者同时删数据,可能会有数据不存在的异常。感觉不靠谱。

问题

如果写者对数据要修改?

解决1

只能使用先删除,后写入的逻辑,读到的数据具有不确定性,可能是新数据,也可能是老数据,因为线程切换的代码点,谁也不知道。也有可能读不到数据啊,但是数据真的有,只是在修改,这是个大问题。难道设个标志位修改中,这样不是让读者全部阻塞了。。不靠谱,并发度不行啊。

解决2

写时复制,如果是修改,则另外新写数据,不影响读者读老数据,只有数据写入成功后,更换老版本?还是保留版本。

结论

一个写着,多个读者的问题可以通过一个写入标志位和一个删除标志位解决。

问题

如果是多个写者呢?

解决

每个写者写一部分区域,分而治之的思想,大化小+hash映射。。。。。

总结

      并发,多线程,事务都是分不开的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值