• 四川郎酒股份有限公司获第十二届人民企业社会责任奖年度环保奖 2019-05-13
  • 银保监会新规剑指大企业多头融资和过度融资 2019-05-12
  • 韩国再提4国联合申办世界杯 中国网友无视:我们自己来 2019-05-11
  • 中国人为什么一定要买房? 2019-05-11
  • 十九大精神进校园:风正扬帆当有为 勇做时代弄潮儿 2019-05-10
  • 粽叶飘香幸福邻里——廊坊市举办“我们的节日·端午”主题活动 2019-05-09
  • 太原设禁鸣路段 设备在测试中 2019-05-09
  • 拜耳医药保健有限公司获第十二届人民企业社会责任奖年度企业奖 2019-05-08
  • “港独”没出路!“梁天琦们”该醒醒了 2019-05-07
  • 陈卫平:中国文化内涵包含三方面 文化复兴表现在其中 2019-05-06
  • 人民日报客户端辟谣:“合成军装照”产品请放心使用 2019-05-05
  • 【十九大·理论新视野】为什么要“建设现代化经济体系”?   2019-05-04
  • 聚焦2017年乌鲁木齐市老城区改造提升工程 2019-05-04
  • 【专家谈】上合组织——构建区域命运共同体的有力实践者 2019-05-03
  • 【华商侃车NO.192】 亲!楼市火爆,别忘了买车位啊! 2019-05-03
    • / 11
    • 下载费用:30 金币  

    重庆时时彩白菜平台: 一种基于共享内存的消息传递方法.pdf

    关 键 词:
    一种 基于 共享 内存 消息 传递 方法
      专利查询网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    摘要
    申请专利号:

    CN200910044403.5

    申请日:

    2009.09.25

    公开号:

    CN101763289A

    公开日:

    2010.06.30

    当前法律状态:

    终止

    有效性:

    无权

    法律详情: 未缴年费专利权终止IPC(主分类):G06F 9/54申请日:20090925授权公告日:20131120终止日期:20150925|||授权|||实质审查的生效IPC(主分类):G06F 9/54申请日:20090925|||公开
    IPC分类号: G06F9/54; G06F9/38 主分类号: G06F9/54
    申请人: 中国人民解放军国防科学技术大学
    发明人: 廖湘科; 刘晓建; 戴华东; 任怡; 谭郁松; 吴庆波; 易晓东; 张卫华; 孔金珠; 颜跃进; 董攀; 邵立松; 李姗姗
    地址: 410073 湖南省长沙市砚瓦池正街47号
    优先权:
    专利代理机构: 国防科技大学专利服务中心 43202 代理人: 郭敏
    PDF完整版下载: PDF下载
    法律状态
    申请(专利)号:

    CN200910044403.5

    授权公告号:

    |||101763289B||||||

    法律状态公告日:

    2016.11.09|||2013.11.20|||2010.08.25|||2010.06.30

    法律状态类型:

    专利权的终止|||授权|||实质审查的生效|||公开

    摘要

    本发明公开了一种基于共享内存的消息传递方法,目的是实现多生产者多消费者情形下生产者和消费者之间高并行消息通信。技术方案是先在共享内存中创建并初始化消息槽数组,分配两个变量head和tail;生产者访问消息槽数组时采用比较交换原子指令CAS保证写写冲突不可能发生,消费者访问消息槽数组时采用比较交换原子指令CAS保证多次读取不可能发生。采用本发明可以实现任意场景下多个生产者和多个消费者并行进行消息通信,对于可以使用锁的场景而言,采用本发明的系统性能远优于使用锁的系统性能。

    权利要求书

    权利要求书
    1.  一种基于共享内存的消息传递方法,其特征在于包括以下步骤:
    第一步,在共享内存中创建并初始化消息缓冲区——消息槽数组,消息槽数组每个元素包含一个消息槽及该消息槽对应的状态,每个消息槽处于以下三种状态之一:“有消息”,“无消息”、“使用中”;初始化时所有的消息槽都设置成“无消息”状态,当消息槽被生产者获取后,生产者将消息槽改为“使用中”状态;当生产者将已生产的消息放入消息槽后,它将消息槽状态由“使用中”修改为“有消息”;当处于“有消息”状态的消息槽被消费者获得后,消息槽的状态被更新为“使用中”;当消费者获得了完整消息之后,它将消息槽的状态由“使用中”更新为“无消息”;同时,在共享内存中分配两个变量head和tail,并令head=tail=0,这两个变量只能按照递增的方式进行改变,它们的取值被称为版本号;同时,head/tail也是消息槽数组的索引,head指向的编号为head%C的消息槽,tail指向编号为tail%C的消息槽,其中%为求余数运算;
    第二步,第x个生产者Px采用以下方法访问消息槽数组,以插入其生产出的消息,x为小于生产者个数M的自然数:

    2.  1创建生产者Px的私有变量cached_tailx;

    2.  2将当前的tail值缓存到Px的私有变量cached_tailx中;

    2.  3判断cached_tailx是否与head+C相等,若相等则执行用户自定义的“消息缓冲区满”处理流程,然后重新执行步骤2.3,若不相等则转2.4;

    2.  4比较交换原子指令CAS(&tail,cached_tailx,cached_tailx+1),若指令失败则转步骤

    2.  2,否则执行2.5;

    2.  5使用CAS(&stat,无消息,使用中)操作修改cached_tailx指向的消息槽状态,尝试将cached_tailx指向的消息槽的状态设置成“使用中”状态,若操作失败转2.2,否则执行2.6,其中stat为cached_tailx指向的消息槽的状态变量;

    2.  6将消息写入cached_tailx指向的消息槽;

    2.  7释放消息槽:将cached_tailx指向的消息槽的状态由“使用中”更新为“有消息”,释放本生产者私有的临时变量cached_tailx;
    第三步,消费者Cx采用以下方法访问消息槽数组,以获取消息:

    3.  1创建生产者Cx的私有变量cached_headx;

    3.  2将当前的head值缓存到cached_headx中;

    3.  3判断cached_headx是否与tail相等,若相等则执行用户自定义的“消息缓冲区空”处理流程,转步骤3.2,若不相等则转3.4;

    3.  4执行CAS(&head,cached_headx,cached_headx+1)指令,若指令失败则转步骤3.2,否则执行3.5;

    3.  5使用CAS(&statx,有消息,使用中)操作修改cached_headx指向的消息槽状态,尝试将cached_headx指向的消息槽的状态设置成“使用中”状态;若操作失败转3.2,否则执行3.6,其中statx为cached_headx指向的消息槽的状态变量;

    3.  6读取cached_headx指向的消息槽中的消息;

    3.  7释放消息槽:将cached_headx指向的消息槽状态由“使用中”更新为“无消息”,释放本消费者私有的临时变量cached_headx。

    2.  如权利要求1所述的基于共享内存的消息传递方法,其特征在于所述消息槽数组从0开始编号、容量为C,C的大小由生产者或消费者数量、生产者生产消息或消费者消费消息的频度、系统对“消息槽满”事件的容忍程度、系统可用内存综合决定。

    说明书

    说明书一种基于共享内存的消息传递方法
    技术领域
    本发明涉及解决消息的生产者消费者问题的方法,尤其是软件系统中多段并发执行的代码通过访问共享内存的方式传递消息的方法。
    背景技术
    在计算机程序设计中经常遇到多个并发执行的代码之间通过一片共享的内存区域传递消息的情形。一般称产生消息的代码为生产者,处理消息的代码为消费者,二者被统称为任务。此时的消息传递一般这样实现:生产者和消费者在两者都能访问的内存中分配一片内存区域(该区域被称作消息槽),生产者将消息记录在该消息槽,消费者读取该消息槽获得消息。
    由于生产者和消费者一般是异步执行的,可能会在某段时间内出现生产者生产消息的速度快于消费者消费消息的速度。这时,为了避免让生产者被迫等待消费者处理消息或者消息在消费之前被覆盖,程序员一般会分配多个消息槽。这些消息槽的集合被称作消息缓冲区。此时,生产者将消息写入消息缓冲区的某个消息槽,消费者从消息缓冲区的消息槽中读取消息。当不采用任何同步机制时,可能会发生以下三种类型的错误:1)读写冲突:消费者试图读取“生产者正在进行写入的消息槽”,这就造成消费者获得了错误的消息;2)多次处理:多个消费者试图从同一个消息槽读取消息,这就造成了一个消息被多次处理;3)写写冲突:多个生产者试图向同一个消息槽写入消息,这就造成消息的丢失甚至最终产生不正确的消息。
    为了避免发生这种生产者和消费者访问消息缓冲区时相互干扰的情况,通常的做法是使用一个锁(lock)来强制所有的生产者或消费者只能采取串行的方式访问消息缓冲区:生产者和消费者在试图访问某个消息槽前,必须先试图获得整个消息缓冲区的锁,只有成功获得锁后才能继续执行,否则就一直尝试或者睡眠,直到成功获得锁。上锁成功者将在访问消息槽结束后释放已获得的锁,并且有可能唤醒睡眠在该锁上的执行者(生产者或消费者)。这种方式使得在同一个时刻最多只能有一个生产者或消费者访问消息缓冲区中的消息槽,虽然使得不再出现任何访问冲突,但也有如下缺点:
    首先,这种基于锁的方法限制了软件系统的并发性。当生产者、消费者访问不同的消息槽时,实际上并不冲突,它们可以并发运行,但当使用锁?;ふ鱿⒒撼迩沟谜庵植⒎⒉辉倏赡?。
    其次,当不能成功获得锁的生产者/消费者转入睡眠时,系统运行的开销很大。由于消费者或生产者一般仅在获得锁后执行很少的几条指令就释放锁,而睡眠和唤醒则需要执行大量的指令,睡眠会严重影响访问消息缓冲区的性能。
    第三,当不能成功获得锁的生产者/消费者一直尝试获得锁时,系统很容易出现死锁。当采用固定优先权时,若低优先权的一方获得了锁,但高优先权的一方获得了CPU执行权,系统会出现死锁:获得了CPU执行权的一方无法获得锁,一直尝试;低优先权的一方获得了锁,但没有机会在CPU上运行。
    最后,当生产者、消费者不是传统操作系统中的线程、进程时,这种方法并不适用。如当操作系统内核通过共享缓冲区与核外线程进行消息通信时,操作系统内核无条件优先于核外线程运行,且内核不是一个线程,若内核获得锁不成功不能转入睡眠。
    目前关于生产者和消费者问题最好的解决方案是非阻塞缓冲区NBB(Non-BlockingBuffer)方法。它没有上述缺点,可有效地解决单个生产者和单个消费者之间的消息传递问题。NBB方法为:为一个环形消息缓冲区设立head和tail两个指针,消费者只关心head所指向的消息槽,在消费完消息后将head调整为指向当前head指向消息槽的下一个消息槽;生产者只关心tail所指向的消息槽,在生产完消息后将tail调整为当前tail指向消息槽的下一个消息槽。只要二者不相等,生产者和消费者之间就不会同时访问一个消息槽,从而不会出现任何访问冲突;当head与tail相等时定义消息缓冲区为空,生产者在完成生产后才将tail的值调整为指向下一个消息槽,从而在head和tail相等时只有生产者访问消息缓冲区。
    NBB的主要缺点是:仅支持单生产者单消费者问题。如多个消费者同时访问head所指向的消息槽将导致消息被多次处理的错误,多个生产者同时访问tail所指向的消息槽将导致产生写写冲突。
    在有些多生产者多消费者系统中,可以采取设置生产者锁来解决写写冲突,采取设置消费者锁来防止消息被多次处理。但对于不同生产者具有不同CPU执行优先权的场合,有可能会出现低优先权的生产者获得了锁,但高优先权的生产者获得了CPU执行权,由于获得CPU执行权的一方无法获得锁,而获得锁的一方又没有机会释放锁,从而出现死锁。
    一般的说,对于有M个生产者、N个消费者的情形,NBB要求设立M*N个非阻塞缓冲区,这会浪费大量的存储空间,且程序设计不便。更重要的是,消费者之间不能自动进行负载平衡:存放在第j(j为小于M的自然数)个消费者消息缓冲区中的消息不能被现在处于空闲状态的第i(i为小于N的自然数)个消费者使用。
    发明内容
    本发明要解决的技术问题是:提供一种新的基于共享内存的消息传递方法,实现多生产者多消费者情形下生产者和消费者之间高并行消息通信。
    本发明的技术方案是:
    本发明的技术方案包括以下步骤:
    1在共享内存中创建并初始化消息缓冲区——消息槽数组。消息槽数组从0开始编号、容量为C,C的大小由生产者(消费者)数量、生产者(消费者)生产(消费)消息的频度、系统对“消息槽满”事件的容忍程度、系统可用内存等因素综合决定。每个元素包含一个消息槽及该消息槽对应的状态。每个消息槽处于以下三种状态之一:“有消息”,“无消息”、“使用中”。初始化时所有的消息槽都设置成“无消息”状态。当消息槽被生产者获取后,生产者将消息槽改为“使用中”状态,以便阻止其它生产者和消费者使用本消息槽;当生产者将已生产的消息放入消息槽后,它将消息槽状态由“使用中”修改为“有消息”;当处于“有消息”状态的消息槽被消费者获得后,消息槽的状态被更新为“使用中”,消费者就可以安全的访问存放在本消息槽中的消息了;当消费者获得了完整消息之后,它将消息槽的状态由“使用中”更新为“无消息”。
    在共享内存中分配两个变量head和tail,并令head=tail=0。在本发明中,每当生产者和消费者成功获取了某个消息槽的独占式访问权限时,head或tail的值都将被加1。因此在一段时间内head和tail的值是否发生过变化就反映了是否有生产者或消费者在本段时间内改变过消息槽数组的状态,所以它们的取值被称为版本号。同时,head和tail也是消息槽数组的索引。head指向的编号为head%C的消息槽,tail指向编号为tail%C的消息槽,其中%为求余数运算。
    由于计算机系统硬件字长有限,head和tail的值可能会因为溢出而重新变为0,进而导致head和tail又变回了它的某个初始值。记head和tail从取值为value到下次取值再次为value所经历的最短时间为Tv,则在head和tail发生变化时,连续两次获取相同值必须至少间隔Tv。记生产者一次存放消息期间连续两次访问tail或消费者一次获取消息期间连续两次访问head的时间间隔最大为Ta(这个时间间隔包含了程序指令执行时间和因为调度带来的睡眠时间)。则在对head和tail进行“加1”操作时,由于计算机字长至少为32位(即head和tail溢出的时间大于232次“加1”操作),因此Ta<Tv,故当生产者发现tail的值没有发生变化时,tail的值实际上也一定没有发生过变化;当消费者发现head的值没有发生变化时,head的值实际上一定没有发生过变化。而一般做法是将head和tail增到缓冲区大小C时就将head和tail置0,这将导致Tv过小,使得虽然head和tail值发生过变化,但生产者和消费者看不到这个变化。
    2第x(x为小于生产者个数M的自然数)个生产者Px采用以下方法访问消息槽数组,以插入其生产出的消息:
    2.1创建生产者Px的私有变量cached_tailx;
    2.2将当前的tail值缓存到Px的私有变量cached_tailx中;
    2.3判断cached_tailx是否与head+C相等,若相等则表示消息槽数组没有可用的消息槽,执行用户自定义的“消息缓冲区满”处理流程(如等待或报错等),然后转到步骤2.2,若不相等则转2.4;这个判断保证了生产者不可能试图去覆盖未被消费的消息。
    2.4比较交换原子指令CAS(&tail,cached_tailx,cached_tailx+1),若指令失败则转步骤2.2,否则执行2.5。
    大多数微处理器均支持CAS指令,不支持CAS指令的微处理器一般均提供可以模拟CAS功能的类似指令。CAS指令可以用函数CAS(addr,old_value,new_value)来表示,其含义为:若在CAS指令执行时内存地址addr处的值为old_value,则将其修改为new_value,并返回操作成功;否则addr处的值保持不变,返回操作失败。在CAS(&tail,cached_tail,cached_tail+1)中,&tail表示获取tail变量的内存地址。CAS指令具有一个很重要的性质:即使系统中存在多个微处理器,硬件保证CAS指令都只能串行执行,不可能出现在同一个时刻有多于1个处理器同时执行CAS指令的情况。
    若多个生产者,如生产者P0和生产者P1都缓存了当前tail的最新值,记这些缓存值为cached_tail0=cached_tail1=...=Y。由于CAS指令执行的串行性,在同一时刻只能有一个生产者执行CAS指令。设生产者P0成功执行了CAS指令,则tail值被更新为Y+1。当P1执行CAS时会出现其cached_tail1为Y而tail>Y,从而CAS指令会执行失败,P1必须重新尝试,在重新尝试时tail的值将大于Y,而P0只操作版本号Y所指向的消息槽,由此写写冲突不可能发生。
    2.5使用CAS(&stat,无消息,使用中)操作修改cached_tailx指向的消息槽状态,尝试将cached_tailx指向的消息槽的状态设置成“使用中”状态。若操作失败转2.2,否则执行2.6。其中stat为cached_tailx指向的消息槽的状态变量。
    一般说来cached_tailx指向的消息槽状态应该是无消息,但有些生产者若在执行步骤2.4和2.5之间暂时放弃了CPU,则有可能会出现cached_tailx指向的消息槽状态不为无消息的情形。如:设生产者Px刚执行完步骤2.4时cached_tailx对应消息槽的状态为无消息,但在执行2.5前由于操作系统调度的原因Px暂时停止执行,则head和tail在其它生产者和消费者的作用下会继续增长。有可能在某一时刻tail会等于cached_tailx+C。此时,别的生产者也会获得与本生产者同样的消息槽,并修改了消息槽的状态。这时若Px恢复执行,会发现消息槽的状态不是无消息。
    若本步骤执行成功,则cached_tailx指向的消息槽的状态被设置成“使用中”状态,这保证了生产者Px对于该消息槽的访问是独占式的。
    步骤2.4和步骤2.5不能颠倒。假设生产者先执行2.5,然后执行2.4,则若低优先权的生产者修改了消息槽状态,但没有来得及调整tail的值就被高优先权的生产者抢先执行了,高优先权的生产者将发现消息槽已被标为使用中,但是它没有办法去尝试下一个消息槽,从而造成死锁。
    2.6将消息写入cached_tailx指向的消息槽。
    具体的写入方法因应用而异。为了缩短消息写入时间,建议在执行步骤2.2前首先将消息写入另外一片共享内存区,在本步骤仅写入存放消息的内存地址。
    2.7释放消息槽:将cached_tailx指向的消息槽的状态由“使用中”更新为“有消息”,释放本生产者私有的临时变量cached_tailx。
    3消费者Cx(x为小于生产者个数N的自然数)采用以下方法访问消息槽数组,以获取消息:
    3.1创建生产者Cx的私有变量cached_headx;
    3.2将当前的head值缓存到cached_headx中;
    3.3判断cached_headx是否与tail相等,若相等则说明所有的消息槽都为“无消息”状态,执行用户自定义的“消息缓冲区空”处理流程(如等待或报错等),转步骤3.2,若不相等则转3.4;
    这个判断保证了消费者和生产者不可能访问同一个消息槽,从而避免了读写冲突。
    3.4执行CAS(&head,cached_headx,cached_headx+1)指令,若指令失败则转步骤3.2,否则执行3.5。
    若多个消费者都缓存了当前head的最新值,记这些缓存值为cached_head0=cached_head1=...=Z。由于CAS指令执行的串行性,在同一时刻只能有一个消费者执行CAS指令。设Cx成功执行了CAS指令,则head值被更新为Z+1。其它的消费者在执行CAS时会出现其cached_head为Z而head>Z,从而CAS指令会执行失败,这些失败者必须重新尝试,在重新尝试时head的值将大于Z,而Cx则只操作版本号Z所指向的消息槽,由此多次读取不可能发生。
    3.5使用CAS(&statx,有消息,使用中)操作修改cached_headx指向的消息槽状态,尝试将cached_headx指向的消息槽的状态设置成“使用中”状态。若操作失败转3.2,否则执行3.6。其中statx为cached_headx指向消息槽的状态变量。
    一般说来cached_headx指向的消息槽应该为有消息状态,但若有些消费者在执行步骤3.4和3.5之间暂时放弃了CPU,则有可能会出现cached_headx指向的消息槽不是有消息状态。如:设消费者Cx刚执行完步骤3.4时cached_headx对应消息槽的状态为有消息,但在执行3.5前Cx因某种原因暂时停止了运行,则head和tail在其它生产者和消费者的作用下会继续增长。有可能在某一时刻head会等于cached_headx+C。此时,别的消费者者也会获得与本生产者同样的消息槽,若别的消费者成功的执行了步骤3.5,则该消息槽的状态会变为使用中。这时若Cx恢复执行,会发现消息槽的状态不是有消息。若本步骤执行成功,则可保证了消费者Cx对于cached_headx所指向的消息槽的访问是独占式的。
    一般说来,由于消费者能处理各种类型的消息,它们之间具有不同的优先权没有什么实际意义,所以3.4和3.5两个步骤可以颠倒,但按照3.4和3.5的顺序性能会更高些。
    3.6获取cached_headx指向的消息槽中的消息。
    3.7释放消息槽:将cached_headx指向的消息槽状态由“使用中”更新为“无消息”,释放本消费者私有的临时变量cached_headx。
    采用本发明可以达到以下技术效果:
    采用本发明可以实现任意场景下多个生产者和多个消费者并行进行消息通信。对于可以使用锁的场景而言,采用本发明的系统性能远优于使用锁的系统性能。
    附图说明
    图1是本发明总体流程图;
    图2为本发明第二步生产者生产消息的流程图;
    图3为本发明第三步消费者消费消息的流程图;
    图4为本发明与基于锁实现的系统进行的“平均发送一条消息所用的时间”的比较示意图。
    具体实施方式
    图1为本发明的总体流程图。
    第一步,在共享内存中创建消息槽数组。
    第二步,生产者在有消息要放入消息槽时进行消息插入;消费者在需要消费消息时进行消息获取。
    图2为本发明中生产者生产消息的流程图。
    此执行流程与公知的生产者消费者问题中生产者的执行流程基本相同,区别主要在于消息槽的获取和释放过程,即图2中的虚线展开部分。
    生产者获取消息槽的流程如下:
    第一步,创建一个本生产者私有的临时变量cached_tailx;
    第二步,将当前tail的值放入cached_tailx变量中;
    第三步,若tail的值等于head+C,则执行缓冲区满的处理流程,然后转第二步;否则继续执行;
    第四步,执行CAS(&tail,cached_tailx,cached_tailx+1)操作,若失败,则转第二步;否则继续执行;
    第五步,执行CAS(&statx,无消息,使用中)操作。其中&statx为cached_tailx所指向消息槽的状态变量的地址,若失败,则转第二步;否则表明获得消息槽成功,。
    生产者释放消息槽的流程为:
    第一步,将cached_tailx指向的消息槽状态由“使用中”改为“有消息”;
    第二步,释放本生产者私有的临时变量cached_tailx。
    图3为本发明中消费者消费消息的流程图。
    此执行流程与公知的生产者消费者问题中消费者的执行流程基本相同,区别主要在于消息槽的获取和释放过程,即图3中的虚线展开部分。
    消费者获取消息槽的流程如下:
    第一步,创建一个本消费者私有的临时变量cached_head;
    第二步,将当前head的值放入cached_headx变量中;
    第三步,若head的值等于tail,则执行缓冲区空的处理逻辑,然后转第二步;否则继续执行;
    第四步,执行CAS(&head,cached_headx,cached_headx+1)操作,若失败,则转第二步;否则继续执行;
    第五步,执行CAS(&statx,有消息,使用中)操作。其中&statx为cached_headx所指向消息槽的状态变量的地址,若失败,则转第二步;否则表明获得消息槽成功。
    消费者释放消息槽的流程为:
    第一步,将cached_headx指向的消息槽状态由“使用中”改为“无消息”;
    第二步,释放本消费者私有的临时变量cached_headx。
    图4为本发明与基于锁实现的系统进行的“平均发送一条消息所用的时间”的比较示意图。经对采用锁机制的系统和采用本发明的系统消息平均发送时间进行评测,评测表明,当生产者和消费者数量均为1时,采用锁机制的系统和采用本发明的系统消息平均发送时间均较小,分别为1.24微秒和0.55微秒;随着生产者和消费者数量的增加,基于锁的系统的消息发送时间快速增长,而采用本发明的系统则具有较好的可扩展性,如当生产者和消费者均为6个时,基于锁的系统平均发送一条消息需要耗时13.34微秒,而采用本发明的系统平均发送一条消息则只需要4.31微秒?!  ∧谌堇醋宰ɡ鴚ww.www.4mum.com.cn转载请标明出处

    关于本文
    本文标题:一种基于共享内存的消息传递方法.pdf
    链接地址://www.4mum.com.cn/p-5781983.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    [email protected] 2017-2018 www.4mum.com.cn网站版权所有
    经营许可证编号:粤ICP备17046363号-1 
     


    收起
    展开
  • 四川郎酒股份有限公司获第十二届人民企业社会责任奖年度环保奖 2019-05-13
  • 银保监会新规剑指大企业多头融资和过度融资 2019-05-12
  • 韩国再提4国联合申办世界杯 中国网友无视:我们自己来 2019-05-11
  • 中国人为什么一定要买房? 2019-05-11
  • 十九大精神进校园:风正扬帆当有为 勇做时代弄潮儿 2019-05-10
  • 粽叶飘香幸福邻里——廊坊市举办“我们的节日·端午”主题活动 2019-05-09
  • 太原设禁鸣路段 设备在测试中 2019-05-09
  • 拜耳医药保健有限公司获第十二届人民企业社会责任奖年度企业奖 2019-05-08
  • “港独”没出路!“梁天琦们”该醒醒了 2019-05-07
  • 陈卫平:中国文化内涵包含三方面 文化复兴表现在其中 2019-05-06
  • 人民日报客户端辟谣:“合成军装照”产品请放心使用 2019-05-05
  • 【十九大·理论新视野】为什么要“建设现代化经济体系”?   2019-05-04
  • 聚焦2017年乌鲁木齐市老城区改造提升工程 2019-05-04
  • 【专家谈】上合组织——构建区域命运共同体的有力实践者 2019-05-03
  • 【华商侃车NO.192】 亲!楼市火爆,别忘了买车位啊! 2019-05-03
  • 最新零点棋牌现金版 北京赛车pk10怎么投注 广东快乐10分开奖直播电视版 上海时时乐开奖走势图 四川时时彩平台下载手机版 2000点股票指数是什么 神龙点波一波中特 吃鸡游戏如何设置最好 阿里巴巴股票行情 腾讯分分彩 王牌彩票苹果 安徽25选5在哪个台开奖 重庆乒乓球吧 地下城勇士网页游戏 海南环岛赛彩票下载 关于玩电子游戏的英语作文