线程安全

前段时间看到了一个完成读比较高的协程库-libgo,里面提供了线程安全的协程实现,并且也是使用锁。本来我并没有给libcopp里的功能加锁的打算,因为上层dispatcher还是比较容易做到安全分发的,所以原来并不保证线程安全。而且线程安全这种问题单元测试比较难写,可能还得碰点运气。但是思来想去,还是为线程安全做点什么吧。反正也不是很复杂。

由于我并没有给utils加互斥锁的跨平台适配,所以先就直接用了自旋锁,来锁住需要考虑线程安全的地方。其实需要加锁的地方并不多,无非是管理器的增删查和task的next函数需要加锁。这些逻辑都很短,功能也很简单,并不会占用太多时间,所以自旋锁的问题也不大。而且以后真发现有问题,换掉也不是什么难事儿。

在写这篇文章前,我突然想到以前流行了一段时间的服务器面试题:当一个BUG只有几百万分之一的概率会出现,怎么办?这个问题在这个BUG里只是毛毛雨而已,因为这次的BUG的出现概率是夸张的三亿分之一

最近一直没什么时间整理近期碰到的问题,今天思考了一下之前碰到的一个临时处理的BUG,顺便写点东西清理一下思路。

其实严格来说这个BUG更应该是一个流程试用问题,不过这个问题应该是需要能在协程库里检测并抛出错误来。

这个问题起源于以前给客户端写的一个log模块,然后里面为了线程安全且多线程下不互相写乱,并且因为这些系统基本都用比较高版本的编译器,都支持C++11了,所以就用了C++11的TLS功能。

慢慢一点一点看看Boost,这段时间就Asio库吧。 据说这货和libevent的效率差不多,但是Boost的平台兼容性,你懂得。还有它帮忙干掉了很多线程安全和线程分发的事情。

这是我对C++新特性系统学习的最后一部分,之后就靠实践中再来看新标准的新特性啦。

在之前,我对这部分没太在意,直到看到了一篇文章 [http://blog.csdn.net/pongba/article/details/1659952](http://blog.csdn.net/pongba/article/details/1659952) 才意识到,C++的多线程操作也是个麻烦的问题。

简而言之,C++编译器在进行编译优化的时候,认为当前是单进程的,并且遵循**可观察行为**(Observable Behavior)不变的原则。就是说在可观察行为不变的情况下,操作是可以被改变顺序的,而单进程可观察行为不变,不代表在多进程的情况下仍然不变。还是上大牛的例子:

_**例子一:**_

完全可以优化成