<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[cenchure的专栏]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/cenchure</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; cenchure]]></copyright><item><title><![CDATA[面向对象----抽象的应用]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/17100763</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/17100763</guid><author>cenchure</author><pubDate>Tue, 03 Dec 2013 21:55:10 +0800</pubDate><description><![CDATA[抽象与分解是面向对象编程中的基本方法。人类理解问题的方式通常是抽象出一类问题的定义，然后根据这个定义来认识问题。通常抽象可分3类： 

             1. 抽象名词定义:  

                        就是大家已经对一些社会或自然界已经存在的事物已经有了抽象的定义了。比如森林，森林是个抽象的定义，表示有很多不同树木和其他植物组成的地方。如果我们程序里要表]]></description><category></category></item><item><title><![CDATA[临界区CriticalSection 的安全使用]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16996143</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16996143</guid><author>cenchure</author><pubDate>Thu, 28 Nov 2013 01:42:31 +0800</pubDate><description><![CDATA[临界区 是应用程序互斥多线程的常用锁。 通常分4个步骤： 初始化（ InitializeCriticalSection),进入临界区(EnterCriticalSection),离开（LeaveCritclSection).,释放(DeleteCriticalSection).

    隐患： 

         1.  InitializeCriticalSection 可能]]></description><category></category></item><item><title><![CDATA[sleep(0) 与sleep(>0)区别]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16994969</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16994969</guid><author>cenchure</author><pubDate>Thu, 28 Nov 2013 00:11:14 +0800</pubDate><description><![CDATA[sleep （1） 与sleep (0)的区别与线程的优先级有关系。
线程创建后，会进入线程调度队列。 线程调度队列通常按线程的优先级分成多个队列。 每个优先级都会有一个队列。 

sleep(1)函数的调用会使线程进入等待状态。这个时候线程上下文会被切换出去。
调用sleep(0) 的时候， 如果调度器中不存在优先级 >= 该线程优先级的情况下，该线程将会继续运行。否则，线程会被放入到其]]></description><category></category></item><item><title><![CDATA[自旋锁的应用]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16994117</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16994117</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 22:50:01 +0800</pubDate><description><![CDATA[通常自旋锁分三种： 纯自旋，队列自旋锁和MCS 锁。 MCS 锁也是基于队列自旋锁的。 但最基本的还是纯自旋锁了。 
自旋锁使用场景： 



  1. 通常在一些需要短暂等待的情况下被使用。通常用sleep（0）  也可以办到，但sleep无法控制不切换上下文。

  2. 当多线程锁使用。通常系统底层用来同步多个CPU访问。

纯自旋锁实现如下： 

class Spin]]></description><category></category></item><item><title><![CDATA[乐观锁的实现与应用]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16993365</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16993365</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 22:02:04 +0800</pubDate><description><![CDATA[乐观锁就是尽量让大家共享使用资源，当真的发生了资源的重要改变的时候，才给共享使用资源的所以线程一个通知，收到通知的线程回滚之前的行为。乐观锁通常在数据库使用，数据库大概比较适合回滚吧。


一般程序代码里面可能很难回滚，所以通常不适用。
但扩展一下概念，比如 new  一个指针变量，传递给多个线程。里面可能都会使用它，但只能有一个线程可以释放它，但不知道是哪个线程。当然，这里假设new 这]]></description><category></category></item><item><title><![CDATA[临界区，互斥体，信号量三种锁的区别]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16991803</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16991803</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 20:56:57 +0800</pubDate><description><![CDATA[三种锁各有优缺点： 

    1 .效率 

             临界区是轻量级的锁，通常不会产生内核对象。其内部实现是基于自旋锁与事件对象等待来实现锁定的。 互斥体与信号量都是内核对象，效率比临界区差。
    2.重入 

          临界区与互斥体都是可以重入的，也就是不会锁定自己线程的多次进入。多线程锁粒度比较粗的时候， 且互相调用，重入的可能性很大，是否支持]]></description><category></category></item><item><title><![CDATA[singleton 模式的多线程安全创建]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16991273</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16991273</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 20:03:53 +0800</pubDate><description><![CDATA[单例模式是通过类的静态函数直接获取对象，并且通过静态变量的特性保证一个进程只有一个该对象。这种模式的类在UML 里与其他类关系通常只是表现为“依赖”关系而已，应该说这个模式可以在设计上一定程度上帮我们解耦。其通常设计如下：




class A{
public:

    static A* CreateInstance()
   {
      static A* pIns]]></description><category></category></item><item><title><![CDATA[volatile 的用法]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16990739</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16990739</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 19:34:39 +0800</pubDate><description><![CDATA[volatile 变量声明通常表达为经常变化的变量。实际的用处有2个： 

  1. 告诉CPU 读取时每次都要从内存中取，不能直接读缓存（CPU通常对变量的访问是直接从缓存中访问）。
  2. VC ++ 里通常是告诉编译器不要优化，移动，volatile 变量相关的代码。就是相当于一个编译器的内存栅栏。


通常应用场景有2个： 



 1. 多线程里作为条件变量原子访问]]></description><category></category></item><item><title><![CDATA[共享与伪共享]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16990009</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16990009</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 18:58:32 +0800</pubDate><description><![CDATA[共享就是一个内存区域的数据被多个处理器访问，伪共享就是不是真的共享。这里的共享这个概念是基于逻辑层面的。实际上伪共享与共享在cache line 上实际都是共享的。


CPU访问的数据都是从cache line  中读取的。如果cpu 在cache 中找不到需要的变量，则称缓存未命中。 未命中时，需要通过总线从内存中读取进cache 中。每次读取的内存大小就是一个cache line 的大]]></description><category></category></item><item><title><![CDATA[lock free 实现多线程安全链表]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16988005</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16988005</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 17:29:15 +0800</pubDate><description><![CDATA[lock free  实现的多线程链表通常无法避免 ABA问题。ABA 问题的实质就是我们刚释放的内存可能会被马上又分配出来，被其他线程又放入到链表里了，导致Interlock函数判断链表节点没有改变（实际上节点已经被删除过一次了，链表发生了改变），而导致错误。


   那么解决方法最有3中：  一种不使用 interlock函数，一种就是在内存中增加计数标志，一种就是不释放内存。]]></description><category></category></item><item><title><![CDATA[lock free 单写多读的循环内存]]></title><link>https://blog.youkuaiyun.com/cenchure/article/details/16986811</link><guid>https://blog.youkuaiyun.com/cenchure/article/details/16986811</guid><author>cenchure</author><pubDate>Wed, 27 Nov 2013 16:39:59 +0800</pubDate><description><![CDATA[lcok free 的单写多读循环内存从无锁的单写单读循环内存变化而来。所以这个问题分2节来介绍： 

  . 单写单独 循环内存
  . lock free 单写多读循环内存


1. 常规的单写单读循环内存通过设置读指针和写指针保证了线程的安全。 其实现如下：

 写数据到内存里(m_uWritePos 声明为volatile ，m_iSize 为内存数组大小)

unsi]]></description><category></category></item></channel></rss>