线程间的数据共享

    恩,估计又要有人说我写的不知所云了,不过先写了再说吧。
    最近做多线程的东东,有很多线程间同步、互斥、临界区和数据传递的问题要解决。
    今天刚刚解决的问题是这样的:我有一个程序,CAN通讯的,简单的说就是网络通讯的。其中有一个监视线程,专门负责监视网络,并将网络当中的所有报文打印出来。可是有这样的现象,当网络通讯量大的时候,程序必然跑死,而且占用大量内存。当通讯量很小的时候,随机的仍然会跑死,同样占用大量内存。花了近半个月解决的所有的内存泄露问题,确认没有内存泄露的时候,问题仍然出现。
    在上个星期的不断测试当中,终于发现这样程序死亡的时候,CPU总是停在了监视线程的消息处理函数当中(系统函数,可不是我写的)。我最终不得不得出这样的结论,windows XP的用户消息机制在默些情况下,也会造成大量的内存占用和死机的。
   
     仔细分析,我认为:尽管消息机制很好,很快,但是,他毕竟是操作系统提供的,因而不可避免进入核心态。换句话说,使用消息机制需要在用户太和核心态之间切换。这样的开销很大。因而,消息,互斥,事件等等,最好不要用来传递数据。
    我就犯了这样的错误,用消息附带数据来进行线程间的数据传递。实验证明,这样的效率并不高,系统占用巨大,并且可能使得线程的消息队列溢出而死机。
 
    那怎么办呢?我采用了数据区共享。FIFO真的是好东西。可以批量处理,一次性装入多个报文,则大大减少了发送消息的次数,减少了线程同步的次数。FIFO的基本结构大家都清楚,除了数组还有读写下标。因为读下标和写下标都只可能被一个线程更改,因而完全没有冲突的问题。同时由于报文数组的存在,完全可以装入多个报文才同步一次,减少了系统态与用户态的转换次数。
    实验结果表明,采用了FIFO而非消息实现监视线程之后,由于监视线程产生的消息而死机的现象消除。并且在较高网络通讯负载的情况下,CPU占用率从50%下降到6%。还是非常明显的。
 
    但是,FIFO不是万能的。当网络通讯负载超过了FIFO的缓冲能力,程序会出现内存写操作错误(Access Violation to 0xc0000005)。不过在这样的情况下,监控也失去了意义。
 
    得到的经验是,消息、互斥只能用于同步,数据交换还是应当采用内存共享,不过一定要注意全局变量的互斥操作保护。
 
    另外,最近在读一本书,Data Structure & Algorithm Analysis in C++。
    从算法的角度说,由易而难的内容是:语言-〉数据结构-〉算法分析。这本书讲的就是算法分析。读的过程中,突然发现,原来原来学的数据结构还是不够的。同样的算法用不同的数据结构完成将会产生完全不同的结果。我的理解,算法分析就是在数据结构的基础上,讲述如何灵活有效的运用各种数据结构构造是和算法。
    如果读过了清华的《数据结构C语言版》,真的可以读读这本书。只找到英文的,中文的数据结构的书好像还没有翻译到算法分析的内容。

中了两篇

上个星期和这个星期中了两篇论文。都是课题相关的,CANopen的。
 
第一篇是中文的,三月多投的计算机工程与应用,结果申了两个半月,告诉我说不录用。改投测控技术,还要了我100元审稿费。寄过去,两个星期跟踪网站上仍然显示等待审稿费,无奈。打电话问,他们爱理不理的回答我可能是邮局的问题,我告诉他们我从邮编100022的北京工业大学汇款到邮编为100022的测控工程编辑部,不会用两个星期的,他们仍然爱理不理的说可能是邮局的问题。我快怒了,但想想不合适,于是恳求他们查一下,最后终于爱理不理的记下了我的名字。两天后,网站显示汇款收到,又过两天,显示文章可用。两天审稿花了我100大洋,够可以的。
 
第二篇是一个英文的。五月写的,投到了2007 IEEE International Conference on Automation and Logistics(ICAL),今天刚收到邮件,录用了。有些意见,7月10后之前寄回。英文论文看来也不是那么困难,国际会议总共收了1500多篇,录了900多篇,都快70%,不中也难怪哦。不过今年是ICAL的第一届,有是在中国开,也不是什么重量级会议,想必如此吧。不过要3000多人民币,还不知谁出,怎么出呢。
 
流水账完毕。