什么是房地产投资?什么是海外房产投资?房地产投资主要表现在哪几种形式 对于房地产投资而言,主要分为两种:第一种就是追求房产本身价值的上涨,获得投资收益;第二种就是通过房产出租的形式获取每年现金流的收益。 第一种完全适用于我们国内的市场,房产价值在近20年之中,上涨速度极快,但目前上涨趋势放缓了很多。而国际上也有很多城市在过去的十年之中房价上涨幅度很大,很多投资人也通过低位买入房产在高位抛售房产的方式赚取了不菲的差价收益。 第二种,就是通过将房屋短期或长期出租获取稳定现金流的投资方式。我国目前的房产租金收益在1%到2%之间,收益率在国际上属于偏低的水平,也就是我们常说的租售比偏低。而在在一些旅游业发达的地区或者名校聚集的地区,房租收益率往往会很高。所以我们在考虑投资目标的时候,一定要明确自己的投资是更倾向于房价上涨带来的本金收益,还是更倾向于稳定的现金流回收。 对于子女的教育来讲,国内的教育环境,教育质量和受教育的公平程度往往迫使大量人群选择将子女送往海外接受更先进的国际教育。虽然选择何种教育的方式,是每个人的自由,但是让子女接触不同的文化已经成为目前的主流趋势。伴随着子女在海外接受教育,海外置业几乎成为每一个家长的必要选择。有些家长说送子女出国留学,可以选择租房呀,但每一个选择租房的家长,在子女毕业之后都极为后悔。因为多年海外学习的生活成本中,房租花费的占比十分巨大,若在孩子出国时进行房产投资,那么利用房屋升值或房屋出租获得的收益与留学费用相抵,你会发现留学成本会大大降低,甚至会赚取不菲的收益。 在海外投资房产开始的越早,也就能更早攀上房地产阶梯。 那么,目前,柬埔寨什么资源最被投资人看好呢? 首先,我们来分析:土地有什么魔力?为什么各国投资家们,不管主业是做什么的,都会想法持有大量的土地? 第一、土地是永远存在的一种资产。20年、50年、100年以后,500年以后都会存在。 我们做投资,要投资哪些?简单来说,起码几十年之后,你知道它还存在的东西。 为什么有些人不会去投股票,因为20年之后还有没有那家公司,真的不知道!但是,20年之后,买的那块土地一定还存在,它不但永远存在,而且它的价格永远是要上涨的。 而柬埔寨是一个处于全球贸易关口的国家,近年,持续地会有大量外国人口流入。 众所周知:房地产行业的价值,好多专家经常说:长期看人口,哪里人口流入的多,这个地方的房地产的价格一定是会上涨的。而柬埔寨的人口越来越多,土地的面积是不变的。土地的价格是一定会上涨的,这是一件逻辑上特别好理解的事情。 第二,号称遍地是黄金的柬埔寨,近年吸引着全球投资者的快速涌入,可说坐拥天时地利人和;加上中国一带一路政策的提出,让柬埔寨这个沿线国家,再次享受着中国经济高速腾飞所带来的巨大红利。 第三,柬埔寨最大的特色是可以拥有永久产权的土地!而随着目前柬埔寨经济的发展,土地升值在望,未来带给投资者的回报,也是极高的。 第四,土地的位置从根本上决定了它未来的增值能力!位置好的地块,总是更容易升值。如投资的土地,在土地位置上,如拥有得天独厚的优势条件的话,那么,发展前景就会好! 第五,如果投资者购买土地,特别是柬埔寨的大片毛地,如希望通过持有土地来获取增值,他就更需要获取关于城市发展方向方面的专业性意见。 因为,如果你投资的土地,对城市未来发展模式判断错误,就会导致投资者等待更长的时间,来实现其收益;而随着等待时间的增长,资金的时间价值,就会使投资的平均年收益率日趋减少。 第六,还有一个规律,是距离城市交通要道越近的地块,价值越高。 如果你购买市区中的地块,必须十分注意土地本身的特性。如地块的位置、轮廓、给排水设施、地基质量及规划等,可能都对它的价值产生影响。 最后,不得不说: 不管是你作为投资者,投资土地的目的是为了开发,还是为了投机;土地地理位置以及土地属性的选择,都是投资成功的重要影响因素。另外,土地投资时机的选择、开发成本及社会、对该土地的开发项目的态度,都将影响到投资者。 "钱能生钱这个道理,懂并不难;难的是从0到1,第一桶金从何而来",这是大家最经常听到的一句话。 我们再来看,当年广东、深圳等沿海城市,那些土豪实现财富自由,甚至高于财富自由的大佬们,哪个不是顺应了时代的潮流,做了所在行业开拓者的角色。 所以,在这个商机信息大爆炸的时代,可能会有越来越多的投资机会涌现。但多数认为,在柬埔寨土地投资这一版块,应是另有天时、地利、人和的优势。 打工也好、创业也好、投资也好、终究还是要顺势而为。毕竟顶着风口浪尖是很容易被拍死在沙滩上的。


煌夫子: 随着一场铺天盖地的大雪,路面结冰、气温下降等易造成骨折的因素逐渐增加。本期【你问我答】,我们就髓内技术的有关问题采访了烟台毓璜顶医院创伤骨科孙煜杰副主任医师。 患者:什么是髓内钉固定技术? 髓内钉内固定术是将大小、长短适合的髓内钉置于骨折断端的骨髓腔内,并于骨折近端、远端给予固定,使骨折得以固定的手术。 髓内钉和骨可形成一种复合结构,共同承担负荷。这种复合结构的机械特性由髓内钉的特性以及骨的质量和完整性决定。内植 物位于骨干的中央,贴近骨干的轴线,可以最佳的抵抗弯力。 髓内钉技术产生于100年前,发展于上世纪中叶,90年代后引入我国,历经多次改进换代。因为其微创切口小、感染风险低、对骨膜破坏少、中心固定、可以早期活动等鲜明优点逐渐得到广泛应用。 患者:那么髓内钉有哪些种类呢? 根据强度分为: 刚性髓内钉、弹性髓内钉; 根据穿针方式分为: 扩髓、非扩髓; 根据穿钉方向分为: 顺行髓内钉、逆行髓内钉 根据固定方式分为: 锁定髓内钉、非锁定髓内钉 根据材质分为: 不锈钢髓内钉、钛钉、可吸收髓内钉 根据截面形状分为: 空心髓内钉、实心髓内钉 患者:髓内钉固定适用于哪些情况? 1. 管状骨的骨干骨折(包括成人及儿童骨折); 2. 长骨干骨折后骨不连; 3. 长骨干骨折畸形愈合; 4. 长骨干骨折的骨延长短缩; 5. 长骨中段的病理骨折; 6. 关节融合; 7. 长骨关节端骨折使用特殊髓内钉(股骨颈骨折、股骨粗隆间骨折、股骨髁骨折); 8. 骨肿瘤切除术后重建。 患者:与其他相关手术比较,髓内钉固定的优势有哪些? 1. 可以控制骨折部位的轴向力线、带锁髓内钉可以防止骨折旋转畸形、降低了内置物断裂的风险; 2. 采用闭合及微创技术,减少了手术感染率; 3. 减少对骨膜血运的破坏、保留血肿内的有成骨作用的生长因子、扩髓碎屑具有自体植骨效应、肌肉收缩产生微动提供力学刺激等因素促进骨折愈合; 4. 中心固定、弹性固定、应力分散避免应力遮挡作用,再骨折发生率低; 5. 固定牢固可以早期功能锻炼和负重; 6. 内固定取出通过小切口,微创; 患者:俗话说金无足赤,髓内钉固定也有缺点吧? 1. 骨髓腔的直径限制了髓内钉的使用; 2. 在控制旋转方面不如钢板及外固定; 3. 扩髓破坏骨内膜血运、影响内侧骨皮质; 4. 扩髓导致骨髓成分入血,可导致脂肪栓塞; 5. 适用范围受限:干骺端骨折、开放性骨折不能使用髓内钉; 患者:传统骨折切开复位内固定术缺点 1. 骨的部分血运来自骨膜与周围软组织,尽管在手术中注意轻巧仔细操作,但软组织与骨膜的剥离仍不可避免地会破坏血运,使骨折端的坏死区增大,引起迟愈合,甚至不愈合。 2. 切开复 位时,血肿的清除必将干扰人体自身的修复能力,影响骨折愈合的过程与时间。 3. 更严重的是切开复位术使闭合性骨折人为地变为开放性骨折,增加了感染的机会。因为骨折部位的组织由于暴力的作用,本来已有严重损伤,手术势必增加局部损伤,影响血运,使局部组织抵抗力进一步降低,细菌更容易在切口内生长、繁殖。一旦发生感染,后果严重,不但给伤员带来不必要的痛苦,甚至还可能造成残疾。 4. 切开复位术必将引起软组织之间,或软组织与骨之间的粘连,如粘连广泛,特别是关节附近的粘连,将影响关节功能的恢复。 相对而言,髓内钉固定是一种相对安全有效的微创治疗手段,在小切口、愈合快、固定牢、早负重等方面有很大优势,成为现代治疗骨折及骨肿瘤的主流方式。 在实际工作中我们应该严格掌握其适应症,合理选择治疗时机,并结合其它有效方法,能充分展现髓内固定技术的优势,提高骨科患者治疗效果,改善病人的生活质量。 相对而言,髓内钉固定是一种相对安全有效的微创治疗手段,在小切口、愈合快、固定牢、早负重等方面有很大优势,成为现代治疗骨折及骨肿瘤的主流方式。 在实际工作中我们应该严格掌握其适应症,合理选择治疗时机,并结合其它有效方法,能充分展现髓内固定技术的优势,提高骨科患者治疗效果,改善病人的生活质量。 相关链接 孙煜杰,烟台毓璜顶医院创伤骨科、骨与软组织肿瘤科副主任医师,医学硕士。 山东省医学会骨科分会青年委员;中华数字医学会骨科分会委员;烟台市中西医结合学会副主任委员。 近年来承担及参与国家及省市级课题10余项,多项获得省、市级科学技术进步奖,发表国内外论著30余篇,参编著作3部。 毓医专家等你来提问~ 【你问我答】是由烟台毓璜顶医院推出的一档线上专家科普答疑公益栏目,坚持"传播健康知识,提供专业服务"的宗旨,努力从患者角度出发,注重功能全面便捷,信息实用可及,医患和谐互动,为公众科普健康知识。 如果你也有医疗健康方面的疑难困惑,欢迎在【你问我答】栏目下方留言提问,我们将挑选大家共同关注的话题,邀请毓医专家为大家答疑解惑!


db s学习笔记 分类: 基本知识 工具介绍 lin x2012-06-11 10:20 2080人阅读 评论(2) 收藏 举报 stringmethodssignalsmsinterfacefeat res 目录(?)[+]  作者:jerry_chen  时间:2010-10-12 阅读:513 次 原文链接 [收藏] 整页浏览 摘要:db s作为一个轻量级的ipc被越来越多的平台接受,在meego中db s也是主要的进程间通信方式,这个笔记将从基本概念开始记录笔者学习db s的过程 [1] db s学习笔记一:db s学习的一些参考资料 [2] db s学习笔记二:什么是db s? [3] db s学习笔记三:db s的一些基本概念 一些基本概念的解释和翻译:  一个完整的db s学习教程(强烈推荐,写得相当的全): 两个db s的完整示例,相当有参考价值  1showart_l .comzengzhaonongblogitem670b98d6e63ae42c07088bael db s官方网站,最原滋原味的db s学习内容 s  s-t toriall  s-specificationl 欢迎大家提供更多的db s学习资料,一起研究 db s是一种ipc机制,由freedesktop.org项目提供,使用gpl许可证发行,用于进程间通信或进程与内核的通信。注:lin x中的ipc通信机制还包括,管道(fifo),共享内存,信号量,消息队列,socket等。db s进程间通信主要有三层架构: 1.底层接口层:主要是通过libdb s这个函数库,给予系统使用db s的能力。 2.总线层:主要message b s daemon这个总线守护进程提供的,在lin x系统启动时运行,负责进程间的消息路由和传递,其中包括lin x内核和lin x桌面环境的消息传递。总线守护进程可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。 3.应用封装层:通过一系列基于特定应用程序框架将db s的底层接口封装成友好的wrapper库,供不同开发人员使用(db s官方主页 s,提供了大部分编程语言的db s库版本)。比如libdb s-glib, libdb s-python. 如上图所示,b s daemon process是运行在lin x系统中的一个后台守护进程,db s-daemon运行时会调用libd s的库。application process1代表的就是应用程序进程,通过调用特定的应用程序框架的wrapper库与db s-daemon进行通信。 从上图也可以看出来application和daemon中其实还是通过socket进行通行。 db s的三大优点:低延迟,低开销,高可用性。 *低延迟:db s一开始就是用来设计成避免来回传递和允许异步操作的。因此虽然在application和daemon之间是通过socket实现的,但是又去掉了socket的循环等待,保证了操作的实时高效。 *低开销:db s使用一个二进制的协议,不需要转化成像xml这样的文本格式。因为db s是主要用来机器内部的ipc,而不是为了网络上的ipc机制而准备的.所以它才能够在本机内部达到最优效果。 *高可用性:db s是基于消息机制而不是字节流机制。它能自动管理一大堆困难的ipc问题。同样的,db s库被设计来让程序员能够使用他们已经写好的代码。而不会让他们放弃已经写好的代码,被迫通过学习新的ipc机制来根据新的ipc特性重写这些代码。 在介绍基本概念之前,先介绍一个学习db s的好工具d-feet,这个工具主要是用来查看db s的system b s和session b s中的各个消息连接的。当然,你也可以在这里面添加自己创建的消息总线,以便于观察。 下面根据上图介绍一下db s中的一些基本概念。 会话总线(session b ses)普通进程创建,可同时存在多条。会话总线属于某个进程私有,它用于进程间传递消息。 系统总线(system b s)在引导时就会启动,它由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。当然,如果一个应用程序需要接受来自系统总线的消息,他也可以直接连接到系统总线中,但是他能发送的消息是受限的。 b s name按字面理解为总线名称貌似不是很贴切,应该是一个连接名称,主要是用来标识一个应用和消息总线的连接。从上图可以看出来,总线名称主要分为两类 "org.kde.stat snotifierwatcher"这种形式的称为公共名(well-knownname) ":1.3"这种形式的称为唯一名(uniq e name) 公共名提供众所周知的服务。其他应用通过这个名称来使用名称对应的服务。可能有多个连接要求提供同个公共名的服务,即多个应用连接到消息总线,要求提供同个公共名的服务。消息总线会把这些连接排在链表中,并选择一个连接提供公共名代表的服务。可以说这个提供服务的连接拥有了这个公共名。如果这个连接退出了,消息总线会从链表中选择下一个连接提供服务。 唯一名以":"开头,":"后面通常是圆点分隔的两个数字,例如":1.0"。每个连接都有一个唯一名。在一个消息总线的生命期内,不会有两个连接有相同的唯一名。拥有公众名的连接同样有唯一名,例如在前面的图中,"org.kde.stat snotifierwatcher"的唯一名是":1.51"。 每个连接都有一个唯一名,但不一定有公共名。 只有唯一名而没有公共名叫做私有连接,因为它们没有提供可以通过公共名访问的服务。 object paths "org.kde.stat snotifierwatcher"这个连接中有三个object paths,标识这这个连接中提供了三个不同的服务,每个object paths表示一个服务。这个路径在连接中是唯一的。 interfaces 在每个object paths下都包含有多个接口(interfaces),举例如下接口: org.freedesktop.db s.introspectable org.freedesktop.db  org.kde.stat snotifierwatcher 红色的两个是消息总线提供的标准接口,而剩下的一个是需要具体的应用去实现的。 methods和signals methods表示可以被具体调用的方法 signals则表示的是信号,此信号可以被广播,而连接了这个信号的对象在接收到信号时就可以进行相应的处理。和qt中的信号应该是一个意思。 d-bus 基础   对d-b s t torial进行了一些翻译加上自己的一些理解。 有很多种ipc或者网络通信系统,如:corba, dce, dcom, dcop, xml-rpc, soap, mbus, internet comm nications engine (ice)等等,可能会有数百种,db s的目的主要是下面两点: 1.在同一个桌面会话中,进行桌面应用程序之间的通讯 2.桌面程序与内核或者守护进程的通信。 db s是一套进程通信体系,它有以下几层: 1.libdb s库,提供给各个应用程序调用,使应用程序具有通信和数据交换的能力,两个应用程序可以直接进行通信,就像是一条socket通道,两个程序之间建立通道之后,就可以通讯了。 2.消息守护进程,在libdb s的基础上创建,可以管理多个应用程序之间的通信。每个应用程序都和消息守护进程建立db s的链接,然后由消息守护进程进行消息的分派。 3.各种包装库,有libdb s-glib,libdb s-qt等等,目的是将db s的底层api进行一下封装。 下面有一张图可以很方便说明db s的体系结构。 db s中的消息由一个消息头(标识是哪一种消息)和消息数据组成,比socket的流式数据更方便一些。b s daemon 就像是一个路由器,与各个应用程序进行连接,分派这些消息。b s daemon 在一台机器上有多个实例,第一个实例是全局的实例,类似于sendmail和或者apache,这个实例有很严格的安全限制,只接受一些特定的系统消息, 用于系统通信。其他b s daemon是一些会话,用于用户登录之后,在当前会话(session)中进行的通讯。系统的b s daemon 和会话的b s daemon 是分开的,彼此不会互相影响,会话b s daemon 不会去调用系统的b s daemon 。 native objects and object paths 在不同的编程语言中,都定义了一些"对象",如java中的java.lang.object,glib中的gobject,qt中的qobject等 等。d-bus的底层接口,和libdb s api相关,是没有这些对象的概念的,它提供的是一种叫对象路径(object path),用于让高层接口绑定到各个对象中去,允许远端应用程序指向它们。object path就像是一个文件路径,可以叫做orgkdekspreadsheets3cells45等。 methods and signals 每个对象都有一些成员,两种成员:方法(methods)和信号(signals),在对象中,方法可以被调用。信号会被广播,感兴趣的对象可以处理这个 信号,同时信号中也可以带有相关的数据。每一个方法或者信号都可以用一个名字来命名,如"frobate" 或者 "onclicked"。 interfaces 每个对象都有一个或者多个接口,一个接口就是多个方法和信号的集合。db s使用简单的命名空间字符串来表示接口,如org.freedesktop.introspectable。可以说db s接口相当于c中的纯虚类。 proxies 代理对象用于模拟在另外的进程中的远端对象,代理对象像是一个正常的普通对象。d-b s的底层接口必须手动创建方法调用的消息,然后发送,同时必须手动 接受和处理返回的消息。高层接口可以使用代理来替换这些,当调用代理对象的方法时,代理内部会转换成db s的方法调用,等待消息返回,对返回结果解包, 返回给相应的方法。可以看看下面的例子,使用db s底层接口编写的代码:message message = new message("remoteobjectpath", "methodname", arg1, arg2); connection connection = getb sconnection; connection.send(message); message reply = connection.waitforreply(message); if (reply.iserror) { } else { object ret rnval e = reply.getret rnval e; } 使用代理对象编写的代码:proxy proxy = new proxy(getb sconnection, "remoteobjectpath"); object ret rnval e = proxy.methodname(arg1, arg2); 客户端代码减少很多。 b s names 当一个应用程序连接上b s daemon时,daemon会分配一个唯一的名字给它。以冒号(:)开始,这些名字在daemon的生命周期中是不会改变的,可以认为这些名字就是一个 ip地址。当这个名字映射到应用程序的连接上时,应用程序可以说拥有这个名字。同时应用可以声明额外的容易理解的名字,比如可以取一个名字 com.mycompany.texteditor,可以认为这些名字就是一个域名。其他应用程序可以往这个名字发送消息,执行各种方法。 名字还有第二个重要的用途,可以用于跟踪应用程序的生命周期。当应用退出(或者崩溃)时,与b s的连接将被os内核关掉,b s将会发送通知,告诉剩余的应用程序,该程序已经丢失了它的名字。名字还可以检测应用是否已经启动,这往往用于只能启动一个实例的应用。 addresses 使用d-b s的应用程序既可以是server也可以是client,server监听到来的连接,client连接到server,一旦连接建立,消息 就可以流转。如果使用db s daemon,所有的应用程序都是client,daemon监听所有的连接,应用程序初始化连接到daemon。 db s地址指明server将要监听的地方,client将要连接的地方,例如,地址: nix:path=tmpabcdef表明 server将在tmpabcdef路径下监听 nix域的socket,client也将连接到这个socket。一个地址也可以指明是 tcpip的socket,或者是其他的。 当使用b s daemon时,libdb s会从环境变量中(dbus_session_bus_address)自动认识"会话daemon"的地址。如果是系统 daemon,它会检查指定的socket路径获得地址,也可以使用环境变量(dbus_session_bus_address)进行设定。 当db s中不使用daemon时,需要定义哪一个应用是server,哪一个应用是client,同时要指明server的地址,这不是很通常的做法。 big concept al pict re 要在指定的对象中调用指定的方法,需要知道的参数如下:address - [b s name] - path - interface - method b s name是可选的,除非是希望把消息送到特定的应用中才需要。interface也是可选的,有一些历史原因,dcop不需要指定接口,因为dcop在同一个对象中禁止同名的方法。 messages - behind the scenes 如果使用db s的高层接口,就可以不用直接操作这些消息。dbus有四种类型的消息: 1.方法调用(method call) 在对象上执行一个方法 2.方法返回(method ret rn)返回方法执行的结果 3.错误(error)调用方法产生的异常 4.信号(signal)通知指定的信号发生了,可以想象成"事件"。 要执行 d-bus 对象的方法,需要向对象发送一个方法调用消息。它将完成一些处理并返回一个方法返回消息或者错误消息。信号的不同之处在于它们不返回任何内容:既没有"信号返回"消息,也没有任何类型的错误消息。 每个消息都有一个消息头,包含多个字段,有一个消息体,包含多个参数。可以认为消息头是消息的路由信息,消息体作为一个载体。消息头里面的字段包含 发送的b s name,目标b s name,方法或者信号名字等,同时消息头里面定义的字段类型规定了消息体里面的数据格式。例如:字符"i"代表了"32-bit integer","ii"就代表了消息体里面有两个"32-bit integer"。 calling a method - behind the scenes 在db s中调用一个方法包含了两条消息,进程a向进程b发送方法调用消息,进程b向进程a发送应答消息。所有的消息都由daemon进行分派,每个调用 的消息都有一个不同的序列号,返回消息包含这个序列号,以方便调用者匹配调用消息与应答消息。调用消息包含一些参数,应答消息可能包含错误标识,或者包含 方法的返回数据。 方法调用的一般流程: 1.使用不同语言绑定的db s高层接口,都提供了一些代理对象,调用其他进程里面的远端对象就像是在本地进程中的调用一样。应用调用代理上的方法,代理将构造一个方法调用消息给远端的进程。 2.在dbus的底层接口中,应用需要自己构造方法调用消息(method call message),而不能使用代理。 3.方法调用消息里面的内容有:目的进程的b s name,方法的名字,方法的参数,目的进程的对象路径,以及可选的接口名称。 4.方法调用消息是发送到b s daemon中的。 5.b s daemon查找目标的b s name,如果找到,就把这个方法发送到该进程中,否则,daemon会产生错误消息,作为应答消息给发送进程。 6.目标进程解开消息,在db s底层接口中,会立即调用方法,然后发送方法的应答消息给daemon。在db s高层接口中,会先检测对象路径,接口, 方法名称,然后把它转换成对应的对象(如gobject,qt中的qobject等)的方法,然后再将应答结果转换成应答消息发给daemon。 7.b s daemon接受到应答消息,将把应答消息直接发给发出调用消息的进程。 8.应答消息中可以包容很多返回值,也可以标识一个错误发生,当使用绑定时,应答消息将转换为代理对象的返回值,或者进入异常。 b s daemon不对消息重新排序,如果发送了两条消息到同一个进程,他们将按照发送顺序接受到。接受进程并需要按照顺序发出应答消息,例如在多线程中处理这些消息,应答消息的发出是没有顺序的。消息都有一个序列号可以与应答消息进行配对。 emitting a signal - behind the scenes 在db s中一个信号包含一条信号消息,一个进程发给多个进程。也就是说,信号是单向的广播。信号可以包含一些参数,但是作为广播,它是没有返回值的。 信号触发者是不了解信号接受者的,接受者向daemon注册感兴趣的信号,注册规则是"match r les",记录触发者名字和信号名字。daemon只向注册了这个信号的进程发送信号。 信号的一般流程如下: 1.当使用db s底层接口时,信号需要应用自己创建和发送到daemon,使用db s高层接口时,可以使用相关对象进行发送,如glib里面提供的信号触发机制。 2.信号包含的内容有:信号的接口名称,信号名称,发送进程的b s name,以及其他参数。 3.任何进程都可以依据"match r les"注册相关的信号,daemon有一张注册的列表。 4.daemon检测信号,决定哪些进程对这个信号感兴趣,然后把信号发送给这些进程。 5.每个进程收到信号后,如果是使用了db s高层接口,可以选择触发代理对象上的信号。如果是db s底层接口,需要检查发送者名称和信号名称,然后决定怎么做。 dbus基础知识  1. 进程间使用d-b s通信 d-b s是一种高级的进程间通信机制,它由freedesktop.org项目提供,使用gpl许可证发行。d-b s最主要的用途是在lin x桌面环境为进程提供通信,同时能将lin x桌面环境和lin x内核事件作为消息传递到进程。d-b s的主要概率为总线,注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。目前,d-b s已被大多数lin x发行版所采用,开发者可使用d-b s实现各种复杂的进程间通信任务。 2. d-b s的基本概念 d-b s是一个消息总线系统,其功能已涵盖进程间通信的所有需求,并具备一些特殊的用途。d-b s是三层架构的进程间通信系统,其中包括: 接口层:接口层由函数库libdb s提供,进程可通过该库使用d-b s的能力。 总线层:总线层实际上是由d-b s总线守护进程提供的。它在lin x系统启动时运行,负责进程间的消息路由和传递,其中包括lin x内核和lin x桌面环境的消息传递。 包装层:包装层一系列基于特定应用程序框架的wrapper库。 d-b s具备自身的协议,协议基于二进制数据设计,与数据结构和编码方式无关。该协议无需对数据进行序列化,保证了信息传递的高效性。无论是libdb s,还是d-b s总线守护进程,均不需要太大的系统开销。 总线是d-b s的进程间通信机制,一个系统中通常存在多条总线,这些总线由d-b s总线守护进程管理。最重要的总线为系统总线(system b s),lin x内核引导时,该总线就已被装入内存。只有lin x内核、lin x桌面环境和权限较高的程序才能向该总线写入消息,以此保障系统安全性,防止有恶意进程假冒lin x发送消息。 会话总线(session b ses)由普通进程创建,可同时存在多条。会话总线属于某个进程私有,它用于进程间传递消息。 进程必须注册后才能收到总线中的消息,并且可同时连接到多条总线中。d-b s提供了匹配器(matchers)使进程可以有选择性的接收消息,另外运行进程注册回调函数,在收到指定消息时进行处理。匹配器的功能等同与路由,用于避免处理无关消息造成进程的性能下降。除此以外,d-b s机制的重要概念有以下几个。 对象:对象是封装后的匹配器与回调函数,它以对等(peer-to-peer)协议使每个消息都有一个源地址和一个目的地址。这些地址又称为对象路径,或者称之为总线名称。对象的接口是回调函数,它以类似c的虚拟函数实现。当一个进程注册到某个总线时,都要创建相应的消息对象。 消息:d-b s的消息分为信号(signals)、方法调用(method calls)、方法返回(method ret rns)和错误(errors)。信号是最基本的消息,注册的进程可简单地发送信号到总线上,其他进程通过总线读取消息。方法调用是通过总线传递参数,执行另一个进程接口函数的机制,用于某个进程控制另一个进程。方法返回是注册的进程在收到相关信息后,自动做出反应的机制,由回调函数实现。错误是信号的一种,是注册进程错误处理机制之一。 服务:服务(services)是进程注册的抽象。进程注册某个地址后,即可获得对应总线的服务。d-b s提供了服务查询接口,进程可通过该接口查询某个服务是否存在。或者在服务结束时自动收到来自系统的消息。 建立服务的流程: - 建立一个db s连接之后 -- db s_b s_get,为这个db s连接(db sconnection)起名 -- db s_b s_req est_name,这个名字将会成为我们在后续进行远程调用的时候的服务名,然后我们进入监听循环 -- db s_connection_read_write。在循环中,我们从总线上取出消息 -- db s_connection_pop_message,并通过比对消息中的方法接口名和方法名 -- db s_message_is_method_call,如果一致,那么我们跳转到相应的处理中去。在相应的处理中,我们会从消息中取出远程调用的参数。并且建立起回传结果的通路 -- reply_to_method_call。回传动作本身等同于一次不需要等待结果的远程调用。发送信号的流程: - 建立一个db s连接之后,为这个db s连接起名,建立一个发送信号的通道,注意,在建立通道的函数中,需要我们填写该信号的接口名和信号名 -- db s_message_new_signal。然后我们把信号对应的相关参数压进去 -- db s_message_iter_init_append; db s_message_iter_append_basic。然后就可以启动发送了 -- db s_connection_send; db s_connection_fl sh。进行一次远程调用的流程: - 建立好db s连接之后,为这db s连接命名,申请一个远程调用通道 -- db s_message_new_method_call,注意,在申请远程调用通道的时候,需要填写服务器名,本次调用的接口名,和本次调用名(方法名)。压入本次调用的参数 -- db s_message_iter_init_append; db s_message_iter_append_basic,实际上是申请了一个首地址,我们就是把我们真正要传的参数,往这个首地址里面送(送完之后一般都会判断是否内存越界了)。然后就是启动发送调用并释放发送相关的消息结构 -- db s_connection_send_with_reply。这个启动函数中带有一个句柄。我们马上会阻塞等待这个句柄给我们带回总线上回传的消息。当这个句柄回传消息之后,我们从消息结构中分离出参数。用db s提供的函数提取参数的类型和参数 -- db s_message_iter_init; db s_message_iter_next; db s_message_iter_get_arg_type; db s_message_iter_get_basic。也就达成了我们进行本次远程调用的目的了。信号接收流程: - 建立一个db s连接之后,为这个db s连接起名,为我们将要进行的消息循环添加匹配条件(就是通过信号名和信号接口名来进行匹配控制的) -- db s_b s_add_match。我们进入等待循环后,只需要对信号名,信号接口名进行判断就可以分别处理各种信号了。在各个处理分支上。我们可以分离出消息中的参数。对参数类型进行判断和其他的处理。db s_connection_read_write -- as long as the connection is open, this f nction will block ntil it can read or write, then read or write, then ret rn #true. if the connection is closed, the f nction ret rns #false.db s_connection_pop_message -- ret rns the first-received message from the incoming message q e e, removing it from the q e e. the caller owns a reference to the ret rned message. if the q e e is empty, ret rns #null.db s_connection_send -- adds a message to the o tgoing message q e e. does not block to write the message to the network; that happens asynchrono sly. to force the message to be written, call db s_connection_fl sh. beca se this only q e es the message, the only reason it can fail is lack of memory. even if the connection is disconnected, no error will be ret rned. @param connection the connection. @param message the message to write. @param serial ret rn location for message serial, or #null if yo don t care @ret rns #true on s ccess.db s_connection_send_with_reply -- q e es a message to send, as with db s_connection_send, b t also ret rns a #db spendingcall sed to receive a reply to the message. if no reply is received in the given timeo t_milliseconds, this f nction expires the pending reply and generates a synthetic error reply (generated in-process, not by the remote application) indicating that a timeo t occ rred. a #db spendingcall will see a reply message before any filters or registered object path handlers. see db s_connection_dispatch for details on when handlers are r n. a #db spendingcall will always see exactly one reply message, nless it s cancelled with db s_pending_call_cancel. if #null is passed for the pending_ret rn, the #db spendingcall will still be generated internally, and sed to track the message reply timeo t. this means a timeo t error will occ r if no reply arrives, nlike with db s_connection_send. if -1 is passed for the timeo t, a sane defa lt timeo t is sed. -1 is typically the best val e for the timeo t for this reason, nless yo want a very short or very long timeo t. there is no way to avoid a timeo t entirely, other than passing int_max for the timeo t to mean "very long timeo t." libdb s clamps an int_max timeo t down to a few ho rs timeo t tho gh. @warning if the connection is disconnected, the #db spendingcall will be set to #null, so be caref l with this. @param connection the connection @param message the message to send @param pending_ret rn ret rn location for a #db spendingcall object, or #null if connection is disconnected @param timeo t_milliseconds timeo t in milliseconds or -1 for defa lt @ret rns #false if no memory, #true otherwise.db s_message_is_signal -- checks whether the message is a signal with the given interface and member fields. if the message is not #dbus_message_type_signal, or has a different interface or member field, ret rns #false.db s_message_iter_init -- initializes a #db smessageiter for reading the arg ments of the message passed in.db s_message_iter_next -- moves the iterator to the next field, if any. if there s no next field, ret rns #false. if the iterator moves forward, ret rns #true.db s_message_iter_get_arg_type -- ret rns the arg ment type of the arg ment that the message iterator points to. if the iterator is at the end of the message, ret rns #dbus_type_invalid. db s_message_iter_get_basic -- reads a basic-typed val e from the message iterator. basic types are the non-containers s ch as integer and string.db s_message_new_signal -- constr cts a new message representing a signal emission. ret rns #null if memory can t be allocated for the message. a signal is identified by its originating object path, interface, and the name of the signal. path, interface, and signal name m st all be valid (the d-b s specification defines the syntax of these fields). @param path the path to the object emitting the signal @param interface the interface the signal is emitted from @param name name of the signal @ret rns a new db smessage, free with db s_message_ nrefdb s_message_iter_init_append -- initializes a #db smessageiter for appending arg ments to the end of a message. @param message the message @param iter pointer to an iterator to initializedb s_message_iter_append_basic -- appends a basic-typed val e to the message. the basic types are the non-container types s ch as integer and string. @param iter the append iterator @param type the type of the val e @param val e the address of the val e @ret rns #false if not eno gh memorydb s_message_new_method_call -- constr cts a new message to invoke a method on a remote object. ret rns #null if memory can t be allocated for the message. the destination may be #null in which case no destination is set; this is appropriate when sing d-b s in a peer-to-peer context (no message b s). the interface may be #null, which means that if m ltiple methods with the given name exist it is ndefined which one will be invoked. the path and method names may not be #null. destination, path, interface, and method name can t contain any invalid characters (see the d-b s specification). @param destination name that the message sho ld be sent to or #null @param path object path the message sho ld be sent to @param interface interface to invoke method on, or #null @param method method to invoke @ret rns a new db smessage, free with db s_message_ nrefdb s_b s_get -- connects to a b s daemon and registers the client with it. if a connection to the b s already exists, then that connection is ret rned. the caller of this f nction owns a reference to the b s. @param type b s type @param error address where an error can be ret rned. @ret rns a #db sconnection with new refdb s_b s_req est_name -- asks the b s to assign the given name to this connection by invoking the req estname method on the b s. first yo sho ld know that for each b s name, the b s stores a q e e of connections that wo ld like to own it. only one owns it at a time - called the primary owner. if the primary owner releases the name or disconnects, then the next owner in the q e e atomically takes over. so for example if yo have an application org.freedesktop.texteditor and m ltiple instances of it can be r n, yo can have all of them sitting in the q e e. the first one to start p will receive messages sent to org.freedesktop.texteditor, b t if that one exits another will become the primary owner and receive messages. the q e e means yo don t need to man ally watch for the c rrent owner to disappear and then req est the name again. @param connection the connection @param name the name to req est @param flags flags @param error location to store the error @ret rns a res lt code, -1 if error is set 给db sconnection起名字(命名) -- 两个相互通信的连接(connection)不能同名 命名规则:  (zeng.xiaolong)db s_b s_add_match -- adds a match r le to match messages going thro gh the message b s. the "r le" arg ment is the string form of a match r le. @param connection connection to the message b s @param r le text al form of match r le @param error location to store any errorsdb s_pending_call_block -- block ntil the pending call is completed. the blocking is as with db s_connection_send_with_reply_and_block; it does not enter the main loop or process other messages, it simply waits for the reply in q estion. if the pending call is already completed, this f nction ret rns immediately. @todo when yo start blocking, the timeo t is reset, b t it sho ld really only se time remaining since the pending call was created. this req ires storing timestamps instead of intervals in the timeo t @param pending the pending calldb s_pending_call_steal_reply -- gets the reply, or ret rns #null if none has been received yet. ownership of the reply message passes to the caller. this f nction can only be called once per pending call, since the reply message is tranferred to the caller. @param pending the pending call @ret rns the reply message or #null. 安装d-b s可在其官方网站下载源码编译,地址为 s.freedesktop.org。或者在终端上输入下列指令: y m install db s db s-devel db s-doc 安装后,头文件位于" srincl dedb s-版本号db s"目录中,编译使用d-b s的程序时需加入编译指令"ˋpkg-config --cflags --libs db s-1ˋ"。 3. d-b s的用例 在使用gnome桌面环境的lin x系统中,通常用glib库提供的函数来管理总线。在测试下列用例前,首先需要安装gtk+开发包(见22.3节)并配置编译环境。该用例一共包含两个程序文件,每个程序文件需单独编译成为可执行文件。 1.消息发送程序 "db s-ding-send.c"程序每秒通过会话总线发送一个参数为字符串ding!的信号。该程序的源代码如下: #incl de  包含glib库 #incl de  包含 glib库中d-b s管理库 #incl de static gboolean send_ding(db sconnection *b s); 定义发送消息函数的原型 int main  { gmainloop *loop;  定义一个事件循环对象的指针 db sconnection *b s;  定义总线连接对象的指针 db serror error;  定义d-b s错误消息对象 loop = g_main_loop_new(null, false);  创建新事件循环对象 db s_error_init (&error);  将错误消息对象连接到d-b s  错误消息对象 b s = db s_b s_get(dbus_bus_session, &error); 连接到总线 if (!b s) {  判断是否连接错误 g_warning("连接到d-b s失败: %s", error.message);  使用glib输出错误警告信息 db s_error_free(&error);  清除错误消息 ret rn 1; } db s_connection_set p_with_g_main(b s, null);  将总线设为接收glib事件循环 g_timeo t_add(1000, (gso rcef nc)send_ding, b s);  每隔1000ms调用一次send_ding函数  将总线指针作为参数 g_main_loop_r n(loop);  启动事件循环 ret rn 0; } static gboolean send_ding(db sconnection *b s)  定义发 送消息函数的细节 { db smessage *message;  创建消息对象指针 message = db s_message_new_signal("comb rtoninidb sding", "com.b rtonini.db s.signal", "ding");  创建消息对象并标识路径 db s_message_append_args(message, dbus_type_string, "ding!", dbus_type_invalid); 将字符串ding!定义为消息 db s_connection_send(b s, message, null);  发送该消息 db s_message_ nref(message);  释放消息对象 g_print("ding!n");  该函数等同与标准输入输出 ret rn true; } main函数创建一个glib事件循环,获得会话总线的一个连接,并将d-b s事件处理集成到glib事件循环之中。然后它创建了一个名为send_ding函数作为间隔为一秒的计时器,并启动事件循环。send_ding函数构造一个来自于对象路径"comb rtoninidb sding"和接口"com.b rtonini.db s.signal"的新的ding信号。然后,字符串ding!作为参数添加到信号中并通过总线发送。在标准输出中会打印一条消息以让用户知道发送了一个信号。 2.消息接收程序 db s-ding-listen.c程序通过会话总线接收db s-ding-send.c程序发送到消息。该程序的源代码如下: #incl de  包含glib库 #incl de  包含glib库中d-b s管理库 static db shandlerres lt signal_filter  定义接收消息函数的原型 (db sconnection *connection, db smessage *message, void * ser_data); int main { gmainloop *loop;  定义一个事件循环对象的指针 db sconnection *b s;  定义总线连接对象的指针 db serror error;  定义d-b s错误消息对象 loop = g_main_loop_new(null, false);  创建新事件循环对象 db s_error_init(&error);  将错误消息对象连接到d-b s  错误消息对象 b s = db s_b s_get(dbus_bus_session, &error);  连接到总线 if (!b s) {  判断是否连接错误 g_warning("连接到d-b s失败: %s", error.message);  使用glib输出错误警告信息 db s_error_free(&error);  清除错误消息 ret rn 1; } db s_connection_set p_with_g_main(b s, null);  将总线设为接收glib事件循环 db s_b s_add_match(b s, "type= signal ,interface = com.b rtonini.db s.signal ");  定义匹配器 db s_connection_add_filter(b s, signal_filter, loop, null);  调用函数接收消息 g_main_loop_r n(loop);  启动事件循环 ret rn 0; } static db shandlerres lt  定义接收消息函数的细节 signal_filter (db sconnection *connection, db smessage *message, void * ser_data) { gmainloop *loop = ser_data;  定义事件循环对象的指针,并与主函数中的同步 if (db s_message_is_signal  接收连接成功消息,判断是否连接失败 (message, dbus_interface_org_freedesktop_local, "disconnected")) { g_main_loop_q it (loop);  退出主循环 ret rn dbus_handler_result_handled; } if (db s_message_is_signal(message, "com.b rtonini.db s.signal", "ping")) {  指定消息对象路径,判断是否成功 db serror error;  定义错误对象 char *s; db s_error_init(&error);  将错误消息对象连接到d-b s错误  消息对象 if (db s_message_get_args  接收消息,并判断是否有错误 (message, &error, dbus_type_string, &s, dbus_type_invalid)) { g_print("接收到的消息是: %sn", s);  输出接收到的消息 db s_free (s);  清除该消息 } else {  有错误时执行下列语句 g_print("消息已收到,但有错误提示: %sn", error.message); db s_error_free (&error); } ret rn dbus_handler_result_handled; } ret rn dbus_handler_result_not_yet_handled; } 该程序侦听db s-ping-send.c程序正在发出的信号。main函数和前面一样启动,创建一个到总线的连接。然后它声明愿意在使用com.b rtonini.db s.signal接口的信号被发送时得到通知,将signal_filter函数设置为通知函数,然后进入事件循环。当满足匹配的消息被发送时,signal_f nc函数会被调用。 如果需要确定在接收消息时如何处理,可通过检测消息头实现。若收到的消息为总线断开信号,则主事件循环将被终止,因为监听的总线已经不存在了。若收到其他的消息,首先将收到的消息与期待的消息进行比较,两者相同则输出其中参数,并退出程序。两者不相同则告知总线并没有处理该消息,这样消息会继续保留在总线中供别的程序处理。 db s实例讲解  网上有不少介绍db s的文章。本文的目标是补充一些简单的例子。 1、db s是什么东西? 网上有一篇叫"d-b s t torial"的文章,流传较广。不少介绍db s的资料,都引用了其中的段落。其实相对于这篇文章,我建议大家直接读"d-b s specification",篇幅不算长,文字也不算枯燥。 d-b s是针对桌面环境优化的ipc(interprocess comm nication )机制,用于进程间的通信或进程与内核的通信。最基本的d-b s协议是一对一的通信协议。但在很多情况下,通信的一方是消息总线。消息总线是一个特殊的应用,它同时与多个应用通信,并在应用之间传递消息。下面我们会在实例中观察消息总线的作用。消息总线的角色有点类似与x系统中的窗口管理器,窗口管理器既是x客户,又负责管理窗口。 支持db s的系统都有两个标准的消息总线:系统总线和会话总线。系统总线用于系统与应用的通信。会话总线用于应用之间的通信。网上有一个叫d-feet的python程序,我们可以用它来观察系统中的db s世界。 图1、由d-feet观察到的d-b s世界 d-b s是一个程序。它提供了api。但我们一般不会直接使用db s的接口。db s-glib是gtk版本的db s接口封装。本文假设读者安装了db s-glib,我安装的是db s-glib-0.76。后面还会看到,通过python操纵db s是多么简单。 2、d-b s的基本概念 2.1、从例子开始 我写了一个最简单的db s服务器,它通过db s提供了一个加法的接口。大家可以下载这个例子。这是一个a totool工程,大家解包后,执行: .a  .config re make 然后在src目录运行: .example-service 这时再运行d-feet,连接session b s,在"b s name"窗口会看到一个叫"org.fmddlmyy.test"连接名。 图2、提供d-b s服务的org.fmddlmyy.test 选择"org.fmddlmyy.test",在右侧窗口点击展开"object paths"-"testobj"-"interfaces"-"org.fmddlmyy.test.basic"-"methods",可以看到一个add方法。双击add方法,弹出下面这个对话框: 图3、通过d-b s接口计算1+2=3 在parameters窗口输入"1,2",点击"exec te"按钮,然后在"o tp t"窗口我们看到了输出结果。我们刚刚创建了一个db s服务并调用了它。 2.2、名词 我们来解释一下d-feet中出现的名词。 2.2.1、b s name 可以把b s name理解为连接的名称,一个b s name总是代表一个应用和消息总线的连接。有两种作用不同的b s name,一个叫公共名(well-known names),还有一个叫唯一名(uniq e connection name)。 、可能有多个备选连接的公共名 公共名提供众所周知的服务。其他应用通过这个名称来使用名称对应的服务。可能有多个连接要求提供同个公共名的服务,即多个应用连接到消息总线,要求提供同个公共名的服务。消息总线会把这些连接排在链表中,并选择一个连接提供公共名代表的服务。可以说这个提供服务的连接拥有了这个公共名。如果这个连接退出了,消息总线会从链表中选择下一个连接提供服务。公共名是由一些圆点分隔的多个小写标志符组成的,例如"org.fmddlmyy.test"、"org.bl ez"。 、每个连接都有一个唯一名 当应用连接到消息总线时,消息总线会给每个应用分配一个唯一名。唯一名以":"开头,":"后面通常是圆点分隔的两个数字,例如":1.0"。每个连接都有一个唯一名。在一个消息总线的生命期内,不会有两个连接有相同的唯一名。拥有公众名的连接同样有唯一名,例如在前面的图中,"org.fmddlmyy.test"的唯一名是":1.17"。 有的连接只有唯一名,没有公众名。可以把这些名称称为私有连接,因为它们没有提供可以通过公共名访问的服务。 d-feet界面上有个"hide private"按钮,可以用来隐藏私有连接。 2.2.2、object paths b s name确定了一个应用到消息总线的连接。在一个应用中可以有多个提供服务的对象。这些对象按照树状结构组织起来。每个对象都有一个唯一的路径(object paths)。或者说,在一个应用中,一个对象路径标志着一个唯一的对象。 "org.fmddlmyy.test"只有一个叫作"testobj"的对象。图1中的"org.bl ez"有多个对象路径。 2.2.3、interfaces 通过对象路径,我们找到应用中的一个对象。每个对象可以实现多个接口。例如:"org.fmddlmyy.test"的"testobj"实现了以下接口: org.fmddlmyy.test.basic org.freedesktop.db s.introspectable org.freedesktop.db  后面讲代码时会看到,我们在代码中其实只实现了"org.fmddlmyy.test.basic"这个接口。接口"org.freedesktop.db s.introspectable"和"org.freedesktop.db "是消息总线提供的标准接口。 2.2.4、methods和signals 接口包括方法和信号。例如"org.fmddlmyy.test"的"testobj"对象的"org.fmddlmyy.test.basic"接口有一个add方法。后面的例子中我们会介绍信号。 标准接口"org.freedesktop.db s.introspectable"的introspect方法是个很有用的方法。类似于java的反射接口,调用introspect方法可以返回接口的xml描述。我们双击 "org.fmddlmyy.test"-"testobj"-"org.fmddlmyy.test.basic"-"org.freedesktop.db s.introspectable"的introspect方法。这个方法没有输入参数,我们直接点击"exec te"按钮,你在"o tp t"窗口看到了什么? 图4、调用introspect方法 后面我们会用另一种方式调用introspect方法。 2.3 小结 "org.fmddlmyy.test"-"testobj"-"org.fmddlmyy.test.basic"-"org.freedesktop.db s.introspectable"的introspect方法,这个描述是不是很麻烦。其实前面还要加上"session b s"。 后面在看客户端的c代码时,我们会看到同样的过程:用db s_g_b s_get得到到session b s的连接。在这个连接上用db s_g_proxy_new_for_name函数获得到拥有指定公共名的连接的指定对象的指定接口的代理。最后,用db s_g_proxy_call函数通过接口代理调用接口提供的方法。 3 下集预告 d-feet虽然很方便,但它使用了python的gtk模块,在一些嵌入式环境可能使用不了。后面会看到,用一个叫db s-send的命令行工具,或者写几行python脚本都可以完成同样的工作。我们还会用一个叫db s-monitor的命令行工具观察db s调用过程中究竟发生了什么? 应用程序a和消息总线连接,这个连接获取了一个众所周知的公共名(记作连接a)。应用程序a中有对象a1提供了接口i1,接口i1有方法m1。应用程序b和消息总线连接,要求调用连接a上对象a1的接口i1的方法m1。 在上一讲的加法例子中,上面这段话可以实例化为:应用程序example-service和会话总线连接。这个连接获取了一个众所周知的公共名"org.fmddlmyy.test"。应用程序example-servic中有对象"testobj"提供了接口"org.fmddlmyy.test.basic",接口"org.fmddlmyy.test.basic"有方法"add"。应用程序d-feet和会话总线连接,要求调用连接"org.fmddlmyy.test"上对象"testobj"的接口"org.fmddlmyy.test.basic"的方法"add"。 应用程序b调用应用程序a的方法,其实就是应用程序b向应用程序a发送了一个类型为"method_call"的消息。应用程序a通过一个类型为"method_ret tn"的消息将返回值发给应用程序b。我们简单介绍一下d-b s总线上的消息。 1、d-b s的消息 上一讲说过最基本的d-b s协议是一对一的通信协议。与直接使用socket不同,d-b s是面向消息的协议。 d-b s的所有功能都是通过在连接上流动的消息完成的。 1.1、消息类型 d-b s有四种类型的消息: method_call 方法调用 method_ret rn 方法返回 error 错误 signal 信号 前面介绍的远程方法调用就用到了method_call和method_ret rn消息。顾名思义,在发生错误时会产生error消息。如果把method_call看作打电话,那么signal消息就是来电了。后面还会详细讨论。 1.2、db s-send和db s-monitor db s提供了两个小工具:db s-send和db s-monitor。我们可以用db s-send发送消息。用db s-monitor监视总线上流动的消息。让我们通过db s-send发送消息来调用前面的add方法,这时db s-send充当了应用程序b。用db s-monitor观察调用过程中的消息。 启动example-service: $ .example-service 在另一个控制台启动db s-monitor: $ db s-monitor db s-monitor默认监视会话总线。执行: $ db s-send --session --type=method_call --print-reply --dest=org.fmddlmyy.test testobj org.fmddlmyy.test.basic.add int32:100 int32:999 输出为: method ret rn sender=:1.21 - dest=:1.22 reply_serial=2 int32 1099 db s-monitor的相关输出包括: signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string ":1.22" string "" string ":1.22" method call sender=:1.22 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=hello method call sender=:1.22 - dest=org.fmddlmyy.test path=testobj; interface=org.fmddlmyy.test.basic; member=add int32 100 int32 999 method ret rn sender=:1.21 - dest=:1.22 reply_serial=2 int32 1099 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string ":1.22" string ":1.22" string "" :1.22就是db s-send在本次调用中与会话总线所建立连接的唯一名。:1.21是连接"org.fmddlmyy.test"的唯一名。在以上输出中我们可以看到:1.22向"org.fmddlmyy.test"发送method_call消息,调用add方法。 :1.21通过method_ret rn消息将调用结果发回:1.22。其它输出信息会在以后说明。 db s-send的详细用法可以参阅手册。调用远程方法的一般形式是: $ db s-send [--system | --session] --type=method_call --print-reply --dest=连接名 对象路径 接口名.方法名 参数类型:参数值 参数类型:参数值 db s-send支持的参数类型包括:string, int32, int32, do ble, byte, boolean。 2、消息总线的方法和信号 2.1、概述 消息总线是一个特殊的应用,它可以在与它连接的应用之间传递消息。可以把消息总线看作一台路由器。正是通过消息总线,d-b s才在一对一的通信协议基础上实现了多对一和一对多的通信。 消息总线虽然有特殊的转发功能,但消息总线也还是一个应用。其它应用与消息总线的通信也是通过1.1节的基本消息类型完成的。作为一个应用,消息总线也提供了自己的接口,包括方法和信号。 我们可以通过向连接"org.freedesktop.db s "上对象""发送消息来调用消息总线提供的方法。事实上,应用程序正是通过这些方法连接到消息总线上的其它应用,完成请求公共名等工作的。 2.2、清单 消息总线对象支持第一讲中提到的标准接口"org.freedesktop.db s.introspectable",我们可以调用org.freedesktop.db s.introspectable.introspect方法查看消息总线对象支持的接口。例如: $ db s-send --session --type=method_call --print-reply --dest=org.freedesktop.db s  org.freedesktop.db s.introspectable.introspect 输出为: method ret rn sender=org.freedesktop.db s - dest=:1.20 reply_serial=2 string " " 从输出可以看到会话总线对象支持标准接口"org.freedesktop.db s.introspectable"和接口"org.freedesktop.db s"。接口"org.freedesktop.db s"有16个方法和3个信号。下表列出了"org.freedesktop.db s"的12个方法的简要说明: org.freedesktop.db s.req estname (in string name, in uint32 flags, o t uint32 reply) 请求公众名。其中flag定义如下: dbus_name_flag_allow_replacement 1 dbus_name_flag_replace_existing 2 dbus_name_flag_do_not_queue 4 返回值reply定义如下: dbus_request_name_reply_primary_owner 1 dbus_request_name_reply_in_queue 2 dbus_request_name_reply_exists 3 dbus_request_name_reply_already_owner 4 org.freedesktop.db s.releasename (in string name, o t uint32 reply) 释放公众名。返回值reply定义如下: dbus_release_name_reply_released 1 dbus_release_name_reply_non_existent 2 dbus_release_name_reply_not_owner 3 org.freedesktop.db s.hello (o t string niq e_name) 一个应用在通过消息总线向其它应用发消息前必须先调用hello获取自己这个连接的唯一名。返回值就是连接的唯一名。db s没有定义专门的切断连接命令,关闭socket就是切断连接。 在1.2节的db s-monitor输出中可以看到db s-send调用消息总线的hello方法。 org.freedesktop.db s.listnames (o t array of string b s_names) 返回消息总线上已连接的所有连接名,包括所有公共名和唯一名。例如连接"org.fmddlmyy.test"同时有公共名"org.fmddlmyy.test"和唯一名":1.21",这两个名称都会被返回。 org.freedesktop.db s.listactivatablenames (o t array of string b s_names) 返回所有可以启动的服务名。db s支持按需启动服务,即根据应用程序的请求启动服务。 org.freedesktop.db s.namehasowner (in string name, o t boolean has_owner) 检查是否有连接拥有指定名称。 org.freedesktop.db s.startservicebyname (in string name, in uint32 flags, o t uint32 ret_val) 按名称启动服务。参数flags暂未使用。返回值ret_val定义如下: 1 服务被成功启动 2 已经有连接拥有要启动的服务名 org.freedesktop.db s.getnameowner (in string name, o t string niq e_connection_name) 返回拥有指定公众名的连接的唯一名。 org.freedesktop.db s.getconnectionunixuser (in string connection_name, o t uint32 nix_ ser_id) 返回指定连接对应的服务器进程的unix用户id。 org.freedesktop.db s.addmatch (in string r le) 为当前连接增加匹配规则。 org.freedesktop.db s.removematch (in string r le) 为当前连接去掉指定匹配规则。 org.freedesktop.db s.getid (o t string id) 返回消息总线的id。这个id在消息总线的生命期内是唯一的。 接口"org.freedesktop.db s"的3个信号是: org.freedesktop.db s.nameownerchanged (string name, string old_owner, string new_owner) 指定名称的拥有者发生了变化。 org.freedesktop.db s.namelost (string name) 通知应用失去了指定名称的拥有权。 org.freedesktop.db s.nameacq ired (string name) 通知应用获得了指定名称的拥有权。 2.3、练习 让我们来试试消息总线提供的方法。 2.3.1、从listname到d-feet的基本逻辑 用db s-send调用: $ db s-send --session --type=method_call --print-reply --dest=org.freedesktop.db s  org.freedesktop.db s.listnames 输出为: method ret rn sender=org.freedesktop.db s - dest=:1.23 reply_serial=2 array [ string "org.freedesktop.db s" string "org.freedesktop.notifications" string "org.freedesktop.tracker" string "org.freedesktop.powermanagement" string ":1.7" string ":1.8" string "org.gnome.screensaver" string ":1.9" string ":1.10" string ":1.22" string ":1.11" string "org.gnome.gnomevfs.daemon" string ":1.23" string ":1.12" string ":1.13" string ":1.0" string ":1.14" string ":1.1" string ":1.15" string ":1.2" string ":1.16" string ":1.3" string "org.gnome.gkbdconfigregistry" string ":1.4" string "org.fmddlmyy.test" string ":1.5" string "org.gnome.settingsdaemon" string ":1.6" ] 这是会话总线当前已连接的连接名。在d-feet窗口的左侧窗口显示的就是listnames返回的连接名。聪明的读者也许已经想到使用消息总线的"org.freedesktop.db s.listnames"方法和各连接的"org.freedesktop.db s.introspectable.introspect",我们就可以像d-feet一样查看总线上所有连接的所有对象的所有接口的所有方法和信号。 你的想法很好。但有一个问题,我们必须对连接中的对象调用"org.freedesktop.db s.introspectable.introspect"方法。 listnames只列出了连接名,我们怎么获取连接中的对象路径呢? 答案很简单,如果我们不知道对象路径就从根目录开始吧。连接中的对象是按照树型结构组织的。我们遍历连接的对象树就可以找到所有的对象。调用对象的"org.freedesktop.db s.introspectable.introspect"方法就可以查看对象的所有接口的所有方法和信号。例如:假设我们不知道连接"org.fmddlmyy.test"里有什么对象,我们可以对根对象""执行: $ db s-send --session --type=method_call --print-reply --dest=org.fmddlmyy.test  org.freedesktop.db s.introspectable.introspect 输出为: method ret rn sender=:1.22 - dest=:1.25 reply_serial=2 string " " "org.fmddlmyy.test"的对象树的根节点只有一个子节点"testobj",再查看"testobj": $ db s-send --session --type=method_call --print-reply --dest=org.fmddlmyy.test testobj org.freedesktop.db s.introspectable.introspect 输出为: method ret rn sender=:1.22 - dest=:1.26 reply_serial=2 string " " 作为一个练习,让我们来查看系统总线的上的bl ez接口。执行: $ db s-send --system --type=method_call --print-reply --dest=org.freedesktop.db s  org.freedesktop.db s.listnames 输出为: method ret rn sender=org.freedesktop.db s - dest=:1.30 reply_serial=2 array [ string "org.freedesktop.db s" string ":1.7" string ":1.8" string ":1.9" string "org.freedesktop.systemtoolsbackends" string ":1.30" string "org.freedesktop.networkmanagerinfo" string ":1.20" string "org.freedesktop.avahi" string ":1.21" string "org.bl ez" string ":1.22" string "org.freedesktop.networkmanager" string "org.freedesktop.consolekit" string ":1.23" string "com.redhat.dhcp" string ":1.13" string ":1.0" string ":1.14" string ":1.1" string ":1.15" string ":1.2" string "org.freedesktop.hal" string "com.redhat.newprinternotification" string ":1.16" string ":1.3" string ":1.17" string ":1.4" string ":1.18" string ":1.5" string ":1.19" string ":1.6" ] 我们看到连接"org.bl ez"。查看它的根对象: $ db s-send --system --type=method_call --print-reply --dest=org.bl ez  org.freedesktop.db s.introspectable.introspect 输出为: method ret rn sender=:1.7 - dest=:1.31 reply_serial=2 string " " 接着查对象"org": $ db s-send --system --type=method_call --print-reply --dest=org.bl ez org org.freedesktop.db s.introspectable.introspect 输出为: method ret rn sender=:1.7 - dest=:1.32 reply_serial=2 string " " 接着查对象"orgbl ez": $ db s-send --system --type=method_call --print-reply --dest=org.bl ez orgbl ez org.freedesktop.db s.introspectable.introspect 输出为: method ret rn sender=:1.7 - dest=:1.33 reply_serial=2 string " " 我们看到了对象"orgbl ez"的所有接口。对象"orgbl ez"还有子节点"service_a dio"、"service_inp t"、"service_network"和"service_serial"。必要时我们可以接着查下去。d-feet的基本逻辑就是这样。后面我们会自己实现一个dteeth。dteeth是命令行程序,可以遍历指定连接的对象树,列出所有对象的所有接口的方法和信号。 2.3.2、listactivatablenames和服务器的自动启动 运行: $ db s-send --system --print-reply --dest=org.freedesktop.db s  org.freedesktop.db s.listactivatablenames 和 $ db s-send --session --print-reply --dest=org.freedesktop.db s  org.freedesktop.db s.listactivatablenames 返回的数据是一样的。在我的电脑上返回的数据是: array [ string "org.freedesktop.db s" string "org.freedesktop.notifications" string "net.ekiga.helper" string "org.freedesktop.powermanagement" string "org.freedesktop.tracker" string "org.freedesktop.systemtoolsbackends.gro psconfig" string "org.freedesktop.systemtoolsbackends.ntpconfig" string "org.gnome.tomboy" string "org.freedesktop.systemtoolsbackends.hostsconfig" string "org.freedesktop.systemtoolsbackends.nfsconfig" string "org.freedesktop.systemtoolsbackends" string "net.ekiga.instance" string "org.gnome.gnomevfs.daemon" string "com.redhat.dhcp" string "org.freedesktop.systemtoolsbackends.timeconfig" string "org.freedesktop.systemtoolsbackends.ifacesconfig" string "org.freedesktop.systemtoolsbackends.servicesconfig" string "org.gnome.rhythmbox" string "org.freedesktop.systemtoolsbackends.platform" string "org.freedesktop.systemtoolsbackends.usersconfig" string "org.freedesktop.systemtoolsbackends.smbconfig" string "org.gnome.settingsdaemon" ] 我们也可以用python脚本调用listactivatablenames。例如:写一个叫的脚本: $ cat  #! srbinenv python import db s b s=db s.systemb s b s_obj=b s.get_object( org.freedesktop.db s ,  ) iface=db s.interface(b s_obj, org.freedesktop.db s ) names=iface.listactivatablenames for n in names: print n 运行: $ . |sort 输出为: com.redhat.dhcp net.ekiga.helper net.ekiga.instance org.freedesktop.db s org.freedesktop.notifications org.freedesktop.powermanagement org.freedesktop.systemtoolsbackends org.freedesktop.systemtoolsbackends.gro psconfig org.freedesktop.systemtoolsbackends.hostsconfig org.freedesktop.systemtoolsbackends.ifacesconfig org.freedesktop.systemtoolsbackends.nfsconfig org.freedesktop.systemtoolsbackends.ntpconfig org.freedesktop.systemtoolsbackends.platform org.freedesktop.systemtoolsbackends.servicesconfig org.freedesktop.systemtoolsbackends.smbconfig org.freedesktop.systemtoolsbackends.timeconfig org.freedesktop.systemtoolsbackends.usersconfig org.freedesktop.tracker org.gnome.gnomevfs.daemon org.gnome.rhythmbox org.gnome.settingsdaemon org.gnome.tomboy 使用python脚本调用db s接口是不是很简单。如果你看过db s-glib的代码(后面会讲解),你对python的简洁会有更深刻的感触。如果你执行: $ cat  srsharedb s-1services #ifndef __db s_glib_marshal_gsm_sms_marshal_h__ #define __db s_glib_marshal_gsm_sms_marshal_h__ #incl de g_begin_decls #ifdef g_enable_debug #define g_marshal_val e_peek_boolean(v) g_val e_get_boolean (v) #define g_marshal_val e_peek_char(v) g_val e_get_char (v) #define g_marshal_val e_peek_ char(v) g_val e_get_ char (v) #define g_marshal_val e_peek_int(v) g_val e_get_int (v) #define g_marshal_val e_peek_ int(v) g_val e_get_ int (v) #define g_marshal_val e_peek_long(v) g_val e_get_long (v) #define g_marshal_val e_peek_ long(v) g_val e_get_ long (v) #define g_marshal_val e_peek_int64(v) g_val e_get_int64 (v) #define g_marshal_val e_peek_ int64(v) g_val e_get_ int64 (v) #define g_marshal_val e_peek_en m(v) g_val e_get_en m (v) #define g_marshal_val e_peek_flags(v) g_val e_get_flags (v) #define g_marshal_val e_peek_float(v) g_val e_get_float (v) #define g_marshal_val e_peek_do ble(v) g_val e_get_do ble (v) #define g_marshal_val e_peek_string(v) (char*) g_val e_get_string (v) #define g_marshal_val e_peek_param(v) g_val e_get_param (v) #define g_marshal_val e_peek_boxed(v) g_val e_get_boxed (v) #define g_marshal_val e_peek_pointer(v) g_val e_get_pointer (v) #define g_marshal_val e_peek_object(v) g_val e_get_object (v) #else #define g_marshal_val e_peek_boolean(v) (v)-data[0].v_int #define g_marshal_val e_peek_char(v) (v)-data[0].v_int #define g_marshal_val e_peek_ char(v) (v)-data[0].v_ int #define g_marshal_val e_peek_int(v) (v)-data[0].v_int #define g_marshal_val e_peek_ int(v) (v)-data[0].v_ int #define g_marshal_val e_peek_long(v) (v)-data[0].v_long #define g_marshal_val e_peek_ long(v) (v)-data[0].v_ long #define g_marshal_val e_peek_int64(v) (v)-data[0].v_int64 #define g_marshal_val e_peek_ int64(v) (v)-data[0].v_ int64 #define g_marshal_val e_peek_en m(v) (v)-data[0].v_long #define g_marshal_val e_peek_flags(v) (v)-data[0].v_ long #define g_marshal_val e_peek_float(v) (v)-data[0].v_float #define g_marshal_val e_peek_do ble(v) (v)-data[0].v_do ble #define g_marshal_val e_peek_string(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_param(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_boxed(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_pointer(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_object(v) (v)-data[0].v_pointer #endif extern void db s_glib_marshal_gsm_sms_boolean__string_string_boxed_pointer_pointer (gclos re *clos re, gval e *ret rn_val e, g int n_param_val es, const gval e *param_val es, gpointer invocation_hint, gpointer marshal_data); void db s_glib_marshal_gsm_sms_boolean__string_string_boxed_pointer_pointer (gclos re *clos re, gval e *ret rn_val e, g int n_param_val es, const gval e *param_val es, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*gmarshalf nc_boolean__string_string_boxed_pointer_pointer) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer arg_3, gpointer arg_4, gpointer arg_5, gpointer data2); register gmarshalf nc_boolean__string_string_boxed_pointer_pointer callback; register gcclos re *cc = (gcclos re*) clos re; register gpointer data1, data2; gboolean v_ret rn; g_ret rn_if_fail (ret rn_val e != null); g_ret rn_if_fail (n_param_val es == 6); if (g_cclosure_swap_data (clos re)) { data1 = clos re-data; data2 = g_val e_peek_pointer (param_val es + 0); } else { data1 = g_val e_peek_pointer (param_val es + 0); data2 = clos re-data; } callback = (gmarshalf nc_boolean__string_string_boxed_pointer_pointer) (marshal_data ? marshal_data : cc-callback); v_ret rn = callback (data1, g_marshal_val e_peek_string (param_val es + 1), g_marshal_val e_peek_string (param_val es + 2), g_marshal_val e_peek_boxed (param_val es + 3), g_marshal_val e_peek_pointer (param_val es + 4), g_marshal_val e_peek_pointer (param_val es + 5), data2); g_val e_set_boolean (ret rn_val e, v_ret rn); } g_end_decls #endif #incl de static const db sgmethodinfo db s_glib_gsm_sms_methods[] = { { (gcallback) gsm_sms_send_message, db s_glib_marshal_gsm_sms_boolean__string_string_boxed_pointer_pointer, 0 }, }; const db sgobjectinfo db s_glib_gsm_sms_object_info = { 0, db s_glib_gsm_sms_methods, 1, "org.freesmartphone.gsm.sms0sendmessage0s0n mber0i0s0contents0i0s0feat remap0i0a{sv}0arg30o0f0n0i000", "org.freesmartphone.gsm.sms0incomingmessage00", "0" }; 在包含绑定文件前,我们必须声明绑定文件要引用的回调函数。 2 对象 2.1 对象定义 db s-glib用gobject实现db s对象。所以我们首先要实现一个对象。在本例中,我们实现一个gsmsms对象,它继承了gobject: $ cat gsm_sms.h #ifndef gsm_sms_h #define gsm_sms_h typedef str ct gsmsms gsmsms; typedef str ct gsmsmsclass gsmsmsclass; str ct gsmsms { gobject parent; }; str ct gsmsmsclass { gobjectclass parent; }; #define gsm_sms_type (gsm_sms_get_type ) gtype gsm_sms_get_type (void); gboolean gsm_sms_send_message (gsmsms *obj, const char *n mber, const char *contents, ghashtable *feat remap, int *ret, gerror **error); void gsm_sms_emit_incoming_message(gsmsms *obj, const char * address, const char * contents, ghashtable *hash); #endif gobject的对象定义虽然繁琐,但有固定的套路。依样画葫芦,画多了就习惯了。我们在gsm_sms.h中声明了gsm_sms_send_message函数。 gsm_sms_send_message函数是在gsm_sms.c中实现的,在绑定文件smss-gl e.h中用到。因为主程序要使用绑定文件中的对象信息,所以应由主程序包含绑定文件。主程序只要在包含绑定文件前包含gsm_sms.h,编译器就不会抱怨gsm_sms_send_message函数未声明。 2.2 信号的列集函数 列集(marshaling)是将数据从某种格式存为流格式的操作;散集(unmarshaling)则是列集的反操作,将信息从流格式中还原出来。在绑定文件中,db s-binding-tool自动生成函数将方法参数从db s消息中还原出来,即实现了散集。那么我们怎么把信号参数由glib的数据结构转换到消息中的数据流呢? 因为gsmsms对象有一个信号,所以在对象类初始化函数gsm_sms_class_init中,我们要调用g_signal_new创建信号。 g_signal_new要求我们提供一个列集函数。 glib有一些标准的列集函数,在gmarshal.h中定义。例如g_cclos re_marshal_void__string,这个函数适合只有一个字符串参数的信号。如果gmarshal.h没有提供适合的列集函数,我们可以用一个叫glib-genmarshal的工具自动生成列集函数。后面我们会看到,无论是标准列集函数还是生成的列集函数都是既可以用于列集也可以用于散集,这些函数通常都被称作列集函数。 使用glib-genmarshal前,我们同样要准备一个输入文件: $ cat sms-marshal.list # see glib-genmarshal(1) for a detailed description of the file format, # possible parameter types are: # void indicates no ret rn type, or no extra # parameters. if void is sed as the parameter # list, no additional parameters may be present. # boolean for boolean types (gboolean) # char for signed char types (gchar) # uchar for nsigned char types (g char) # int for signed integer types (gint) # uint for nsigned integer types (g int) # long for signed long integer types (glong) # ulong for nsigned long integer types (g long) # enum for en meration types (gint) # flags for flag en meration types (g int) # float for single-precision float types (gfloat) # double for do ble-precision float types (gdo ble) # string for string types (gchar*) # param for gparamspec or derived types (gparamspec*) # boxed for boxed (anonymo s b t reference co nted) types (gboxed*) # pointer for anonymo s pointer types (gpointer) # object for gobject or derived types (gobject*) # none deprecated alias for void # bool deprecated alias for boolean void:string,string,boxed 我们需要的函数返回类型是void,参数是string,string,boxed。在中可以这样调用glib-genmarshal: sms-marshal.h: sms-marshal.list $(libtool) --mode=exec te glib-genmarshal --header sms-marshal.list --prefix=sms_marshal  sms-marshal.h sms-marshal.c: sms-marshal.list $(libtool) --mode=exec te glib-genmarshal --body sms-marshal.list --prefix=sms_marshal  sms-marshal.c "--prefix"和函数原型决定输出函数名。如果"--prefix=sms_marshal",函数原型是"oid:string,string,boxed",生成的列集函数名就必然是sms_marshal_void__string_string_boxed。 在本例中自动生成的文件内容如下: $ cat sms-marshal.h #ifndef __sms_marshal_marshal_h__ #define __sms_marshal_marshal_h__ #incl de g_begin_decls extern void sms_marshal_void__string_string_boxed (gclos re *clos re, gval e *ret rn_val e, g int n_param_val es, const gval e *param_val es, gpointer invocation_hint, gpointer marshal_data); g_end_decls #endif $ cat sms-marshal.c #incl de #ifdef g_enable_debug #define g_marshal_val e_peek_boolean(v) g_val e_get_boolean (v) #define g_marshal_val e_peek_char(v) g_val e_get_char (v) #define g_marshal_val e_peek_ char(v) g_val e_get_ char (v) #define g_marshal_val e_peek_int(v) g_val e_get_int (v) #define g_marshal_val e_peek_ int(v) g_val e_get_ int (v) #define g_marshal_val e_peek_long(v) g_val e_get_long (v) #define g_marshal_val e_peek_ long(v) g_val e_get_ long (v) #define g_marshal_val e_peek_int64(v) g_val e_get_int64 (v) #define g_marshal_val e_peek_ int64(v) g_val e_get_ int64 (v) #define g_marshal_val e_peek_en m(v) g_val e_get_en m (v) #define g_marshal_val e_peek_flags(v) g_val e_get_flags (v) #define g_marshal_val e_peek_float(v) g_val e_get_float (v) #define g_marshal_val e_peek_do ble(v) g_val e_get_do ble (v) #define g_marshal_val e_peek_string(v) (char*) g_val e_get_string (v) #define g_marshal_val e_peek_param(v) g_val e_get_param (v) #define g_marshal_val e_peek_boxed(v) g_val e_get_boxed (v) #define g_marshal_val e_peek_pointer(v) g_val e_get_pointer (v) #define g_marshal_val e_peek_object(v) g_val e_get_object (v) #else #define g_marshal_val e_peek_boolean(v) (v)-data[0].v_int #define g_marshal_val e_peek_char(v) (v)-data[0].v_int #define g_marshal_val e_peek_ char(v) (v)-data[0].v_ int #define g_marshal_val e_peek_int(v) (v)-data[0].v_int #define g_marshal_val e_peek_ int(v) (v)-data[0].v_ int #define g_marshal_val e_peek_long(v) (v)-data[0].v_long #define g_marshal_val e_peek_ long(v) (v)-data[0].v_ long #define g_marshal_val e_peek_int64(v) (v)-data[0].v_int64 #define g_marshal_val e_peek_ int64(v) (v)-data[0].v_ int64 #define g_marshal_val e_peek_en m(v) (v)-data[0].v_long #define g_marshal_val e_peek_flags(v) (v)-data[0].v_ long #define g_marshal_val e_peek_float(v) (v)-data[0].v_float #define g_marshal_val e_peek_do ble(v) (v)-data[0].v_do ble #define g_marshal_val e_peek_string(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_param(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_boxed(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_pointer(v) (v)-data[0].v_pointer #define g_marshal_val e_peek_object(v) (v)-data[0].v_pointer #endif void sms_marshal_void__string_string_boxed (gclos re *clos re, gval e *ret rn_val e, g int n_param_val es, const gval e *param_val es, gpointer invocation_hint, gpointer marshal_data) { typedef void (*gmarshalf nc_void__string_string_boxed) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer arg_3, gpointer data2); register gmarshalf nc_void__string_string_boxed callback; register gcclos re *cc = (gcclos re*) clos re; register gpointer data1, data2; g_ret rn_if_fail (n_param_val es == 4); if (g_cclosure_swap_data (clos re)) { data1 = clos re-data; data2 = g_val e_peek_pointer (param_val es + 0); } else { data1 = g_val e_peek_pointer (param_val es + 0); data2 = clos re-data; } callback = (gmarshalf nc_void__string_string_boxed) (marshal_data ? marshal_data : cc-callback); callback (data1, g_marshal_val e_peek_string (param_val es + 1), g_marshal_val e_peek_string (param_val es + 2), g_marshal_val e_peek_boxed (param_val es + 3), data2); } 2.3 对象实现 准备好列集函数后,我们来实现gsmsms。 $ cat -n gsm_sms.c 1 #incl de 2 #incl de 3 #incl de 4 #incl de 5 #incl de "gsm_sms.h" 6 #incl de "sms-marshal.h" 7 #incl de "sms_feat res.h" 8 9 en m 10 { 11 incoming_message, 12 last_signal 13 }; 14 15 static g int signals[last_signal]; 16 17 g_define_type(gsmsms, gsm_sms, g_type_object) 18 19 static void gsm_sms_init (gsmsms *obj) 20 { 21 } 22 23 static void gsm_sms_class_init (gsmsmsclass *klass) 24 { 25 signals[incoming_message] = g_signal_new ( 26 "incoming_message", 27 g_object_class_type (klass), 28 g_signal_run_last | g_signal_detailed, 29 0, 30 null, null, 31 sms_marshal_void__string_string_boxed, 32 g_type_none, 3, g_type_string, g_type_string, 33 sms_get_feat res_type); 34 } 35 36 gboolean gsm_sms_send_message (gsmsms *obj, const char *n mber, const char *contents, 37 ghashtable *feat remap, int *ret, gerror **error) 38 { 39 printf("n mber=%sn", n mber); 40 printf("contents=%sn", contents); 41 sms_show_feat res(feat remap); 42 *ret = strlen(contents); 43 ret rn true; 44 } 45 46 void gsm_sms_emit_incoming_message(gsmsms *obj, const char * address, 47 const char * contents, ghashtable *hash) 48 { 49 g_signal_emit (obj, signals[incoming_message], 0, address, contents, hash); 50 } 在类初始化函数gsm_sms_class_init中,我们调用g_signal_new创建了信号。g_signal_new函数的原型是: g int g_signal_new (const gchar *signal_name, gtype itype, gsignalflags signal_flags, g int class_offset, gsignalacc m lator acc m lator, gpointer acc _data, gsignalcmarshaller c_marshaller, gtype ret rn_type, g int n_params, ...); 31行提供了列集函数。32-33行是返回值类型和参数类型。其中第三个参数调用了函数sms_get_feat res_type(在sms_feat res.h中声明)。因为a{sv}类型的参数处理起来比较繁琐,我专门写了一个sms_feat res模块处理,后面会介绍。 在主程序中登记对象信息时,对象信息把sendmessage方法和gsm_sms_send_message函数以及自动生成的散集函数联系起来。当客户程序调用sendmessage方法时,db s-glib会通过对象信息表格找到回调函数和散集函数,用散集函数从method_call消息中取出参数传入回调函数gsm_sms_send_message。 gsm_sms_send_message调用sms_show_feat res函数处理a{sv}参数。 sms_show_feat res也在sms_feat res模块定义,后面会介绍。 gsm_sms模块提供了一个gsm_sms_emit_incoming_message函数供外部模块调用。调用这个函数可以发射一个信号。在真实环境中,只有外部事件发生后才会发射信号。本例中会有测试代码发射信号。 3 主程序 3.1 登记db s服务器 下面就是主程序 $ cat -n smss.c 1 #incl de 2 #incl de 3 #incl de 4 #incl de 5 #incl de "gsm_sms.h" 6 #incl de "smss-gl e.h" 7 #incl de "sms_feat res.h" 8 9 #define smss_debug 10 11 static void lose (const char *str, ...) 12 { 13 va_list args; 14 va_start (args, str); 15 vfprintf (stderr, str, args); 16 fp tc ( n , stderr); 17 va_end (args); 18 exit (1); 19 } 20 21 static void lose_gerror (const char *prefix, gerror *error) 22 { 23 if (error) { 24 lose ("%s: %s", prefix, error-message); 25 } 26 else { 27 lose ("%s", prefix); 28 } 29 } 30 31 static void shell_help(void) 32 { 33 printf( "tstsend signaln" 34 "tqtq itn" 35 ); 36 } 37 38 void emit_signal(gsmsms *obj) 39 { 40 ghashtable *feat res = sms_create_feat res(" cs2", 3, 1); 41 gsm_sms_emit_incoming_message(obj, "", "hello signal!", feat res); 42 sms_release_feat res(feat res); 43 } 44 45 #define stdin_buf_size 1024 46 static gboolean channel_cb(giochannel *so rce, giocondition condition, gpointer data) 47 { 48 int rc; 49 char b f[stdin_buf_size+1]; 50 gsmsms *obj = (gsmsms *)data; 51 52 if (condition != g_io_in) { 53 ret rn true; 54 } 55 56 57 printf("# "); 58 rc = fscanf(stdin, "%s", b f); 59 if (rc = 0) { 60 printf("nulln"); 61 ret rn true; 62 } 63 64 if (!strcmp(b f, "h")) { 65 shell_help; 66 } else if (!strcmp(b f, "?")) { 67 shell_help; 68 } else if (!strcmp(b f, "s")) { 69 emit_signal(obj); 70 } else if (!strcmp(b f, "q")) { 71 exit(0); 72 } else { 73 printf("unknown command ˋ%s n", b f); 74 } 75 ret rn true; 76 } 77 78 int main (int argc, char **argv) 79 { 80 db sgconnection *b s; 81 db sgproxy *b s_proxy; 82 gerror *error = null; 83 gsmsms *obj; 84 gmainloop *mainloop; 85 g int req est_name_res lt; 86 giochannel *chan; 87 88 #ifdef smss_debug 89 g_slice_set_config(g_slice_config_always_malloc, true); 90 #endif 91 g_type_init ; 92 93 db s_g_object_type_install_info (gsm_sms_type, &db s_glib_gsm_sms_object_info); 94 95 mainloop = g_main_loop_new (null, false); 96 97 b s = db s_g_b s_get (dbus_bus_session, &error); 98 if (!b s) 99 lose_gerror ("co ldn t connect to system b s", error); 100 101 b s_proxy = db s_g_proxy_new_for_name (b s, "org.freedesktop.db s", 102 "", "org.freedesktop.db s"); 103 104 if (!db s_g_proxy_call (b s_proxy, "req estname", &error, 105 g_type_string, "org.freesmartphone.ogsmd", 106 g_type_uint, 0, 107 g_type_invalid, 108 g_type_uint, &req est_name_res lt, 109 g_type_invalid)) 110 lose_gerror ("failed to acq ire org.freesmartphone.ogsmd", error); 111 112 obj = g_object_new (gsm_sms_type, null); 113 db s_g_connection_register_g_object (b s, "orgfreesmartphonegsmdevice", g_object (obj)); 114 115 printf ("service is r nningn"); 116 chan = g_io_channel_ nix_new(0); 117 g_io_add_watch(chan, g_io_in, channel_cb, obj); 118 g_main_loop_r n (mainloop); 119 120 exit (0); 121 } 93行调用db s_g_object_type_install_info登记gsmsms类的接口信息。97行连接会话总线。 101-102行在会话总线上为连接"org.freedesktop.db s"的""对象的接口"org.freedesktop.db s"建立代理。 104-109行通过接口代理调用"req estname"方法,请求公共名"org.freesmartphone.ogsmd"。 请求公共名成功后,112行建立gsmsms对象。113行登记gsmsms对象,登记时指定对象路径"orgfreesmartphonegsmdevice",并传入对象指针。118行进入主循环等待客户消息。 3.2 io channel 我想增加一个敲键测试信号发射。但我又必须在glib主循环里等待db s消息。怎样才能既等待db s消息,又等待敲键呢?这种情况可以使用glib的io channels。glib的io channels允许我们在glib主循环等待指定的文件或socket句柄。 要使用io channels,首先包含"glibgiochannel.h"。116行用句柄0(即标准输入)创建一个giochannel。 117行为我们创建的giochannel登记回调函数。我们在回调函数channel_cb中处理敲键,发射信号。 3.3 编译运行 读者可以从这里下载完整的示例程序。下集会介绍本例的a totool工程。目前,我们先编译运行一下,解压后执行: $ .config re $ make $ cd src $ .smss service is r nning h # s send signal q q it 键入h后回车,可以看到敲键的帮助信息。 我想找个客户程序测试一下,db s-send不能发a{sv}这样复杂的参数。我们可以用d-feet测试,或者写个python脚本: $ cat .smsc.py #! srbinenv python import db s b s=db s.sessionb s b s_obj=b s.get_object( org.freesmartphone.ogsmd , orgfreesmartphonegsmdevice ) iface=db s.interface(b s_obj, org.freesmartphone.gsm.sms ) ret=iface.sendmessage(  , hello from python , { alphabet : gsm , csm_n m :8, csm_seq :2}) print "sendmessage ret rn %d" % (ret) 执行smsc.py,在服务器端看到: $ .smss service is r nning h # s send signal q q it n mber= contents=hello from python csm_n m=8 alphabet=gsm csm_seq=2 说明服务器可以正常工作。主程序的89行要求glib直接用malloc分配内存,这样用valgrind才能检查到内存泄漏(如果有的话)。我们可以这样运行smss以检查是否有内存泄漏: $ valgrind --tool=memcheck --leak-check=f ll .smss 4、复杂的数据类型 在db s中怎样处理复杂的数据类型?第一个建议是尽量不要使用复杂的数据类型。但如果确实需要呢?有的网友建议用garray作为容器,不管什么参数,在客户端都手工放入garray,在服务器端再自己取出来。这确实是个思路,比较适合服务器和客户端都是自己开发的情况。还有一篇"how to pass a variant with db s-glib" 介绍了怎样用gval e传递复杂的数据类型,读者可以参考。 下面看看在我们的例子中是怎样处理a{sv}参数的: $ cat sms_feat res.h #ifndef sms_features_h #define sms_features_h #incl de ghashtable *sms_create_feat res(const char * alphabet, int csm_n m, int csm_seq); gtype sms_get_feat res_type(void); void sms_release_feat res(ghashtable *feat res); void sms_show_feat res(ghashtable *feat res); #endif sms_feat res.h声明了几个函数。这个例子的服务器、客户端都会调用。以下是这些函数的实现: $ cat -n sms_feat res.c 1 #incl de "sms_feat res.h" 2 3 static void release_val(gpointer data) 4 { 5 gval e *val = (gval e *)data; 6 g_val e_ nset(val); 7 g_free(val); 8 } 9 10 ghashtable *sms_create_feat res(const char * alphabet, int csm_n m, int csm_seq) 11 { 12 ghashtable *hash; 13 gval e *val; 14 15 hash = g_hash_table_new_f ll (g_str_hash, null, null, release_val); 16 17 val = g_new0(gval e, 1); 18 g_val e_init (val, g_type_string); 19 g_val e_set_string (val, alphabet); 20 g_hash_table_insert(hash, "alphabet", val); 21 22 val = g_new0(gval e, 1); 23 g_val e_init (val, g_type_int); 24 g_val e_set_int (val, csm_n m); 25 g_hash_table_insert(hash, "csm_n m", val); 26 27 val = g_new0(gval e, 1); 28 g_val e_init (val, g_type_int); 29 g_val e_set_int (val, csm_seq); 30 g_hash_table_insert(hash, "csm_seq", val); 31 32 ret rn hash; 33 } 34 35 gtype sms_get_feat res_type(void) 36 { 37 ret rn db s_g_type_get_map("ghashtable", g_type_string, g_type_value); 38 } 39 40 void sms_show_feat res(ghashtable *feat res) 41 { 42 glist *keys = g_hash_table_get_keys(feat res); 43 gint len = g_list_length(keys); 44 gint i; 45 46 for (i = 0; i  len; i) { 47 gchar *key = g_list_nth_data(keys, i); 48 gval e *val = g_hash_table_look p(feat res, key); 49 50 g_print("%s=", key); 51 switch (g_value_type(val)) { 52 case g_type_string: 53 g_print("%sn", g_val e_get_string(val)); 54 break; 55 case g_type_int: 56 g_print("%dn", g_val e_get_int(val)); 57 break; 58 defa lt: 59 g_print("val e is of nmanaged type!n"); 60 } 61 } 62 63 g_list_free(keys); 64 } 65 66 void sms_release_feat res(ghashtable *feat res) 67 { 68 g_hash_table_destroy(feat res); 69 } 70 sms_get_feat res_type调用db s_g_type_get_map创建a{sv}类型。服务器在创建信号时用到。客户端在调用方法和注册信号时都会用到。 sms_create_feat res调用g_hash_table_new_f ll创建哈希表,在创建的同时登记了值对象的清理函数。在sms_release_feat res调用g_hash_table_destroy销毁哈希表时,创建时登记的值对象清理函数会被调用。 5、客户端 5.1、代码 客户端程序如下: $ cat -n smsc.c 1 #incl de 2 #incl de 3 #incl de 4 #incl de 5 #incl de 6 #incl de "sms-marshal.h" 7 #incl de "sms_feat res.h" 8 9 #define smsc_debug 10 11 static void lose (const char *str, ...) 12 { 13 va_list args; 14 va_start (args, str); 15 vfprintf (stderr, str, args); 16 fp tc ( n , stderr); 17 va_end (args); 18 exit (1); 19 } 20 21 static void lose_gerror (const char *prefix, gerror *error) 22 { 23 if (error) { 24 lose ("%s: %s", prefix, error-message); 25 } 26 else { 27 lose ("%s", prefix); 28 } 29 } 30 31 static void incoming_message_handler (db sgproxy *proxy, const char *address, const char *contents, ghashtable *feat res, gpointer ser_data) 32 { 33 printf ("received message with addree "%s" and it says: n%sn", address, contents); 34 sms_show_feat res(feat res); 35 } 36 37 static void send_message(db sgproxy *remote_object) 38 { 39 gerror *error = null; 40 ghashtable *feat res; 41 int ret; 42 43 feat res = sms_create_feat res ("gsm", 8, 2); 44 printf("sendmessage "); 45 46 if (!db s_g_proxy_call (remote_object, "sendmessage", &error, 47 g_type_string, "", g_type_string, "hello world", 48 sms_get_feat res_type, feat res, g_type_invalid, 49 g_type_int, &ret, g_type_invalid)) 50 lose_gerror ("failed to complete sendmessage", error); 51 52 printf("ret rn %dn", ret); 53 sms_release_feat res(feat res); 54 } 55 56 static void shell_help(void) 57 { 58 printf( "tstsend messagen" 59 "tqtq itn" 60 ); 61 } 62 63 #define stdin_buf_size 1024 64 static gboolean channel_cb(giochannel *so rce, giocondition condition, gpointer data) 65 { 66 int rc; 67 char b f[stdin_buf_size+1]; 68 db sgproxy *remote_object = (db sgproxy *)data; 69 70 if (condition != g_io_in) { 71 ret rn true; 72 } 73 74 75 printf("# "); 76 rc = fscanf(stdin, "%s", b f); 77 if (rc = 0) { 78 printf("nulln"); 79 ret rn true; 80 } 81 82 if (!strcmp(b f, "h")) { 83 shell_help; 84 } else if (!strcmp(b f, "?")) { 85 shell_help; 86 } else if (!strcmp(b f, "s")) { 87 send_message(remote_object); 88 } else if (!strcmp(b f, "q")) { 89 exit(0); 90 } else { 91 printf("unknown command ˋ%s n", b f); 92 } 93 ret rn true; 94 } 95 96 int main (int argc, char **argv) 97 { 98 db sgconnection *b s; 99 db sgproxy *remote_object; 100 gerror *error = null; 101 gmainloop *mainloop; 102 giochannel *chan; 103 g int so rce; 104 gtype feat res_type; 105 106 #ifdef smsc_debug 107 g_slice_set_config(g_slice_config_always_malloc, true); 108 #endif 109 g_type_init ; 110 mainloop = g_main_loop_new (null, false); 111 112 b s = db s_g_b s_get (dbus_bus_session, &error); 113 if (!b s) 114 lose_gerror ("co ldn t connect to session b s", error); 115 116 remote_object = db s_g_proxy_new_for_name (b s, "org.freesmartphone.ogsmd", 117 "orgfreesmartphonegsmdevice", 118 "org.freesmartphone.gsm.sms"); 119 if (!remote_object) 120 lose_gerror ("failed to get name owner", null); 121 122 feat res_type = sms_get_feat res_type; 123 db s_g_object_register_marshaller (sms_marshal_void__string_string_boxed, g_type_none, g_type_string, g_type_string, 124 feat res_type, g_type_invalid); 125 db s_g_proxy_add_signal (remote_object, "incomingmessage", g_type_string, g_type_string, feat res_type, g_type_invalid); 126 db s_g_proxy_connect_signal (remote_object, "incomingmessage", g_callback (incoming_message_handler), null, null); 127 128 chan = g_io_channel_ nix_new(0); 129 so rce = g_io_add_watch(chan, g_io_in, channel_cb, remote_object); 130 g_main_loop_r n (mainloop); 131 exit (0); 132 } 112行连接会话总线。116-118行在会话总线上获取连接"org.freesmartphone.ogsmd"的对象"orgfreesmartphonegsmdevice" 的接口"org.freesmartphone.gsm.sms"的接口代理对象。 123行调用db s_g_object_register_marshaller向db s-glib登记列集函数。 125行调用db s_g_proxy_add_signal增加对信号incomingmessage的监听。126行登记信号incomingmessage的回调函数。 123行登记的还是我们用glib-genmarshal生成的函数sms_marshal_void__string_string_boxed。 db s-glib使用这个函数从signal消息中取出信号参数,传递给回调函数,即执行散集操作。这说明glib-genmarshal生成的列集函数既可以用于列集,也可以用于散集。 客户端程序同样用io channel接受用户输入。129行在登记回调函数时将指向接口代理对象的指针作为参数传入。回调函数channel_cb在用户键入 s 命令后通过send_message函数调用org.freesmartphone.gsm.sms接口对象的sendmessage方法。 107行的设置g_slice_config_always_malloc同样是为了用valgrind检查内存泄漏。 5.2、执行 我们先运行 db s-monitor,然后运行smss,再运行smsc。先在smsc中键入 s 回车调用sendmessage方法。然后在smss中键入 s 回车发送incomingmessage信号。然后在smsc中键入 q 回车退出。最后在smss中键入 q 回车退出。 $ .smss service is r nning n mber= contents=hello world csm_n m=8 alphabet=gsm csm_seq=2 h # s send signal q q it s # q $ .smsc h # s send message q q it s # sendmessage ret rn 11 received message with addree "" and it says: hello signal! csm_n m=3 alphabet= cs2 csm_seq=1 q 我们可以看到打印出来的信号和消息。对于同一件事情,不同的层次的观察者会看到不同的细节,下表是db s-monitor看到的东西: smss连接会话总线。会话总线发nameownerchanged信号,通知唯一名":1.21"被分配。 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string ":1.21" string "" string ":1.21" smss向会话总线发送hello取得自己的唯一名":1.21"。 method call sender=:1.21 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=hello smss调用addmatch要求接收会话总线的nameownerchanged信号。 method call sender=:1.21 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=addmatch string "type= signal ,sender= org.freedesktop.db s ,path= orgfreedesktopdb s ,interface= org.freedesktop.db s ,member= nameownerchanged " smss调用addmatch要求接收会话总线发送的所有信号。 method call sender=:1.21 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=addmatch string "type= signal ,sender= org.freedesktop.db s ,path=  ,interface= org.freedesktop.db s " smss调用getnameowner获取连接"org.freedesktop.db s"的唯一名。 method call sender=:1.21 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=getnameowner string "org.freedesktop.db s" 会话总线发送nameownerchanged信号,通知唯一名为":1.21"的连接获得了公众名"org.freesmartphone.ogsmd"。 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string "org.freesmartphone.ogsmd" string "" string ":1.21" smss请求公众名"org.freesmartphone.ogsmd"。分配公众名在前,请求公众名在后,应该是监控过程颠倒了消息次序。 method call sender=:1.21 - dest=org.freedesktop.db s path=; interface=org.freedesktop.db s; member=req estname string "org.freesmartphone.ogsmd" int32 0 smsc连接会话总线。会话总线发nameownerchanged信号,通知唯一名":1.22"被分配。 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string ":1.22" string "" string ":1.22" smss向会话总线发送hello取得自己的唯一名":1.22"。 method call sender=:1.22 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=hello smsc调用addmatch要求接收会话总线的nameownerchanged信号。 method call sender=:1.22 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=addmatch string "type= signal ,sender= org.freedesktop.db s ,path= orgfreedesktopdb s ,interface= org.freedesktop.db s ,member= nameownerchanged " smsc调用addmatch要求接收连接 org.freesmartphone.ogsmd 中对象 orgfreesmartphonegsmdevice 的 org.freesmartphone.gsm.sms 接口的信号。 method call sender=:1.22 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=addmatch string "type= signal ,sender= org.freesmartphone.ogsmd ,path= orgfreesmartphonegsmdevice ,interface= org.freesmartphone.gsm.sms " smsc调用getnameowner获取连接"org.freesmartphone.ogsmd"的唯一名。 method call sender=:1.22 - dest=org.freedesktop.db s path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=getnameowner string "org.freesmartphone.ogsmd" smsc调用连接 org.freesmartphone.ogsmd 中对象 orgfreesmartphonegsmdevice 的 org.freesmartphone.gsm.sms 接口的sendmessage方法。 method call sender=:1.22 - dest=org.freesmartphone.ogsmd path=orgfreesmartphonegsmdevice; interface=org.freesmartphone.gsm.sms; member=sendmessage string "" string "hello world" array [ dict entry( string "csm_seq" variant int32 2 ) dict entry( string "alphabet" variant string "gsm" ) dict entry( string "csm_n m" variant int32 8 ) ] smss向smsc发送method ret rn消息,返回sendmessage方法的输出参数。 method ret rn sender=:1.21 - dest=:1.22 reply_serial=5 int32 11 smss发送incomingmessage信号。 signal sender=:1.21 - dest=(n ll destination) path=orgfreesmartphonegsmdevice; interface=org.freesmartphone.gsm.sms; member=incomingmessage string "" string "hello signal!" array [ dict entry( string "csm_seq" variant int32 1 ) dict entry( string "alphabet" variant string " cs2" ) dict entry( string "csm_n m" variant int32 3 ) ] 会话总线通知连接":1.22",即smsc的连接已经切断。 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string ":1.22" string ":1.22" string "" 会话总线通知拥有公共名"org.freesmartphone.ogsmd"的连接已经切断。 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string "org.freesmartphone.ogsmd" string ":1.21" string "" 会话总线通知拥有唯一名":1.21"的连接已经切断。即smss已经终止。 signal sender=org.freedesktop.db s - dest=(n ll destination) path=orgfreedesktopdb s; interface=org.freedesktop.db s; member=nameownerchanged string ":1.21" string ":1.21" string "" 6、工程 我提供下载的文件要用make distcheck制作的,其中包含了一些自动生成的文件。执行.可以删掉自动生成的文件,只留下我创建的文件: $ find . -type f . . .a  .srcgsm_sms.h .src .srcsms-marshal.list .srcsmss.xml .srcsmss.c .srcgsm_sms.c .srcsms_feat res.h .srcsms_feat res.c .srcsmsc.c .config  前面已经介绍过所有的源文件。我们再看看工程文件: $ cat a  #! binsh to ch ˋfind .ˋ aclocal a toconf a toheader to ch news readme authors changelog a tomake --add-missing $ cat  subdirs = src extra_dist = a   a 建立工程环境。在执行后,执行a 重新生成config re等工程文件。其中的to ch命令是为了防止文件有将来的时间戳。因为我在虚拟机中运行 b nt ,所以可能会出现这类问题。 将a  也作为发布文件。最重要的工程文件是"config "和"src"。 6.1、config  $ cat -n config  1 ac_init 2 am_init_automake(hello-db s5, 0.1) 3 am_config_header(config.h) 4 5 ac_prog_cc 6 7 8 # db s detection 9 pkg_check_modules(dbus, db s-1 = 1.1, have_db s=yes, have_db s=no) 10 11 if test x$have_db s = xno ; then 12 ac_msg_error([db s development libraries not fo nd]) 13 fi 14 am_conditional(have_dbus, test x$have_db s = xyes) 15 16 ac_subst(dbus_cflags) 17 ac_subst(dbus_libs) 18 19 20 # glib detection 21 pkg_check_modules(dbus_glib, gobject-2.0 = 2.6, have_glib=yes, have_glib=no) 22 23 if test x$have_glib = xno ; then 24 ac_msg_error([glib development libraries not fo nd]) 25 fi 26 27 am_conditional(have_glib, test x$have_glib = xyes) 28 29 ac_subst(dbus_glib_cflags) 30 ac_subst(dbus_glib_libs) 31 32 33 ac_output([makefile 34 srcmakefile]) 8-17行检查db s库,它们会生成编译常数dbus_cflags和dbus_libs。 20-30行检查db s-glib库,它们会生成编译常数dbus_glib_cflags和dbus_glib_libs。 6.2、src $ cat -n src 1 includes =  2 $(dbus_cflags)  3 $(dbus_glib_cflags)  4 -ddbus_compilation 5 6 libs =  7 $(dbus_libs)  8 $(dbus_glib_libs)  9 -ldb s-glib-1 10 11 # smss 12 noinst_programs = smss 13 14 built_sources = smss-gl e.h sms-marshal.h sms-marshal.c 15 smss_sources = $(built_sources) smss.c gsm_sms.c sms_feat res.c 16 noinst_headers = gsm_sms.h sms_feat res.h 17 18 19 smss-gl e.h: smss.xml 20 $(libtool) --mode=exec te db s-binding-tool --prefix=gsm_sms --mode=glib-server --o tp t=smss-gl e.h $(srcdir)smss.xml 21 22 sms-marshal.h: sms-marshal.list 23 $(libtool) --mode=exec te glib-genmarshal --header sms-marshal.list --prefix=sms_marshal  sms-marshal.h 24 25 sms-marshal.c: sms-marshal.list 26 $(libtool) --mode=exec te glib-genmarshal --body sms-marshal.list --prefix=sms_marshal  sms-marshal.c 27 28 cleanfiles = $(built_sources) 29 30 extra_dist = smss.xml sms-marshal.list 31 32 # smss 33 noinst_programs += smsc 34 smsc_sources= smsc.c sms-marshal.c sms_feat res.c 19-20行由接口描述文件smss.xml生成存根文件smss-gl e.h。22-26行由列集接口定义生成包含列集函数的代码。 7、结束语 本文介绍了一个简单的db s-glib的例子,包括服务器和客户端。第一讲中还有一个加法例子,如果你理解了本文的例子,那个例子就更简单了。 db s-glib源代码中有两个例子: example-service和example-client演示方法调用。这个例子的接口描述文件中有个参数类型写错了,将( s)写成(ss),运行时会出错。可能作者想演示一下接口定义与代码实现不一致的后果吧。


网络成瘾及其对策 一、网络成瘾的概念 "成瘾"((addiction)一词最初只用于药物依赖,类似的成瘾标准被用于一些行为障碍,如饮食障碍、赌博成瘾、计算机成瘾、电子游戏成瘾及某些技术的过度使用。网络成瘾是指过度使用互联网而导致明显的社会、心理损害的一类现象。这种网络成瘾与赌博成瘾非常相似,均在无成瘾物质作用下的行为冲动失控,导致上网者学业失败、工作表现变差、婚姻不和谐甚至家庭破裂。 二、网络成瘾的现状 美国大学生网络成瘾者的比率:8%~13% 2003年6 月的一个统计资料表明,国内有6800万人上网,其中18~35岁占66.6% 大专以上学历为55. 2% 大学生网络成瘾发生率:9.8%~13% 网上调查自愿填写的问卷,发生率为6%~10% 《中国青少年网瘾数据报告(2005)》:我国青少年网民中上网成瘾者约占13.2%,另有13%的人存在网瘾倾向。报告还提出了"四个有关"、"四个无关"的结论。即中国青少年网络成瘾与性别有关、与年龄有关、与职业有关、与网上活动内容有关。 与所在的地区的地理位置无关、与所在的经济发展水平无关。 三、网络成瘾的原因 1、 网络空间的特点 网络空间是一种精神文化空间,它使现实与虚拟、人工经验与真实世界之间的界限变得模糊起来。在这个虚拟的世界中,会有一些独特的心理体验,包括:灵活而匿名的个人身分 平等的地位 超越空间的界限 易于建立大量的人际关系 变化的梦幻般体验 控制体验 成功体验 2、 上网行为的动力学研究 s ler的研究认为,人们在满足以下的需要(1)性的需要。(2)改变感知体验需要。(3)成就和控制的需要。(4)归属的需要。(5)人际交往的需要(6)要实现和和超越的需要。 3、 网络成瘾与人格因素的相关研究 yo mg用抑郁测评量表调查结果显示,中到重度的抑郁水平与网络成瘾存在相关。yo mg用线性调查法结果显示网络成瘾者为轻到中度的抑郁,推测抑郁是导致网络成瘾的一个主要因素。 与抑郁有关的人格特征,如低自尊、缺乏动机、寻求外界认可、害怕被拒绝等可能是促进网络成瘾的发生的原因。高水平的厌倦倾向、孤独、社交焦虑及及自我封闭均可预测网络成瘾的发生。 逃避某种不良感觉和获取某种需要, 逃避罪恶感、无助感 、抑郁焦虑、在网上寻找慰藉,而网络成瘾又加重了抑郁、焦虑,使精神功能性迟滞、睡眼障碍等心理、生理问题。 网络使用过度的人群有较高的抑郁感。抑郁相关的人格特征:低自尊、缺乏动机、寻求外界认可,害怕被拒绝等等可能成为网络成瘾的原因。 mckenna社交焦虑和网络虚拟关系成显著下正相关。有社交焦虑的人更愿意在网络中寻找朋友,避免在现实中与人面对面门交流时出现焦虑等不良情绪。 人格素质模式的解释: 人格素质模式认为,成瘾源于早年儿童时期所受到的心理创伤,且与某些人的人格特啎或其它障碍、遗传的心理素质相关。异常行为的产生源于性格脆弱和生活事件,存在的病态心理作为一种素质,是网络成瘾产的必要病因,而与网络相关的潜在的病态心理,包括抑郁、社交性焦虑和物质依赖,其本身不会导致出现网络成瘾的症状,但它是病因学中一个必要成分。 认知行为模式的理论解释: 操作性条件反射原理: 四、网络成瘾的症状 1、耐受性:需不断的增加上网时间才能达到原有的满足感;上网的时间及频率比计划的更多更长。 2、戒断症状:停止或减少使用,则出现典型的戒断症状精神运动性激惹、焦虑、有关上网的幻想或做梦、强迫性思考网上的事,及随意或不随意的手指打字动作。 3、病态行为: 上网冲动控制障碍 逃避行为 社交活动减少,宁愿在网上与人交流而不愿进行面对面的交,逃避家庭、工作和社会责任。 网络性行为 否认症状 4、认知性不良 包括对自我的曲解认知:自我怀疑 五、网络成瘾的诊断 目前国内专家对于网瘾的定义有两种不同的观点。一种观点是"习惯说",以陶宏开教授为代表。持有这种观点者认为,网瘾既不是心理疾病,也不是生理疾病,而是一种比较偏激的爱好。青少年上网成瘾,只是行为习惯上出了些偏差,只要适当地矫正,完全可以引导他们戒除网瘾。给网瘾表青年打针吃药是不负责任的做法。一些家长也担心精神药物会给孩子带来不良影响。 另一种观点是"疾病说",持这种观点者以国内率先开展网瘾药物治疗的北京军区总院网络依赖治疗中心主任陶然为代表。陶然认为,网络成瘾不只是一种心理问题,准确地说是一种精神类疾病。患有互联网成瘾综合症的患者,与酒瘾、毒瘾、洁癖等患者一样,其心理都是病态的,程度不同地存在着心理障碍。因此,为了根除网瘾,必须以药物治疗为基础,通过心理治疗把孩子们错误的心理发育扭转到正常的道路上来。 目前对网络成瘾还没有一个标准的疾病分类系统正式将其列为心理障碍之一,也没有公认的诊断标准。bread提出一个研究用的诊断标准。 bread网络成瘾瘾诊断问卷:下列8条中需具备前五项,后三项中致少出现一种: 1、 一心想上网(回想以前的网上活动或期待下一次上网) 2、 需增加更长上网的时间以获得满足感 3、 多次努力控制减少或停止上网,但不能成功。 4、 在努力减少上网时,感到不安,闷闷不乐抑郁或易激怒 5、 上网的时间比计划的要长 6、 因为上网,妨碍或丧失了重要的人际关系和工作或失去了教育与就业的机会 7、 对家人、好友、治疗者说谎,隐瞒卷入上网的程度 8、 把上网作为逃避问题或缓解不良情绪(如无助、嫉妒、无望、焦虑)的方法。 六、网络成瘾的对策 网络成瘾者普遍求治动机不强,与其它成瘾行为相似,是一种自适应的问题行为,通常患者主观上并无太多的不适,患者上网时体验到满足感使其倾向于过度上网而导致的身心危害,除非极端状态影响个人生活,患者较少主动求治。 门诊中求治的通常都是因为因网络成瘾而严重影响了正常的学业、工作和生活,由亲属动员而来,或强行带来。面对这样的患者,如何能争取他们的合作是十分重要的问题。如果不合作,所有的治疗都不能发挥作用。 合肥市的一项调查,2000名中学生中存在网络病和可能存在网络病的人数为3. 5%,其中,高中生人数为5.1 %,初中生为1.9%;男生为5.9%,女生为0.8%。 调查还发现市级重点中学有网络病的学生比普通学校高。省重点学校高于市级重点学校。有网络病的学生学生多出出非重点班级及借读生。这些学生大多家长出重金借读,给于的压力较大,学习成绩往往难以跟上。 学生患网络病于家长的压力也有关。家长对孩子的要求过高,父母关系不和,可能诱发学生寻求虚拟世界回避现实。 结论:网络病源于压力。


原文地址:毛泽东、林彪缘何反目成仇?(二)作者:侯嘉亮著作博克网毛泽东、林彪缘何反目成仇?(二) 陈伯达给毛泽东当了20几年的秘书,又是常委,认为自己是了解主席心思的,也相信了毛想当国家主席的吹风话。再说:林副主席迟早是要接班的,从长远考虑也是要紧跟的。于是他一马当先,支持设国家主席,还搜集了马克思、列宁、毛泽东论天才的语录。 1970年8月23日~9月6日,中共九届二中全会在庐山举行。林彪在开幕会上首先作了长篇讲话,在讲到要设国家主席的同时,又大讲了天才问题。陈伯达还写了有关鼓吹天才论的小册子,广为散发。 林彪对黄、吴、李、邱说:"我告诉你们一个事实。庐山会议前,是毛泽东自己亲自对我至少两次说到,他不想再当党的主席了,要当国家主席,国际上走走,扩大中国的影响,并提醒我发起这个建议。我是奉命做事。而且,你们知道,当时军队和中央党政方面的很多领导,都对那些秀才很反感。江青动员我,想和我结盟,推张春桥当总理。我看清了,如果张当了总理,以后江青就会当党的主席。我可以不接毛主席的班,但是我绝对不能在那样一个女人下工作。" 叶群、吴法宪、邱会作、李作鹏等人按照林彪讲话的调子,纷纷到各小组进行活动。 邱会作在西北组发言说:"林副主席说毛主席是天才,毛泽东思想全面地继承捍卫和发展了马克思列宁主义。这次他仍然坚持这个观点。为什么在文化大革命胜利、二中全会上还讲这个问题?一定是有人反对这种说法,有人说天才地、创造性地、全面地继承、捍卫和发展了马克思列宁主义是一种讽刺,就是把矛头指向毛主席、林副主席。" 8月25日,毛泽东召开政治局扩大会议,批判了陈伯达,责令陈伯达检讨。他一反常态,又不同意设国家主席了,还找林彪谈了话...周恩来找吴法宪、邱会作、李作鹏谈了话,要他们向中央作检查。 毛泽东的战略部署是:先稳住林彪,保持大局稳定。打倒陈伯达。搞臭林彪手下的四员大将黄、吴、李、邱。向军队"掺沙子、挖墙角、甩石头",架空林彪。待一切条件成熟后,再开会更张接班人。 8月31日,全会印发了毛泽东写的《我的一点意见》。批评了英雄创造历史的观点和唯心论的先验论。告械人们:"不要上号称懂得马克思,实际上根本不懂马克思那样一些人的当"并严厉指出陈伯达搞"突然袭击,煽风点火,惟恐天下不乱,大有炸平庐山,停止地球转动之势"。 林彪是何等人物?知道大势已去,如其坐以待毙,不如破釜沉舟!便指示老虎(林立果)组织地下舰队,实施《571工程纪要》-杀害毛主席。571是"武装起义"的谐音。 《纪要》的核心杀毛夺权。说毛泽东"不是一个真正的马列主义者,而是一个行孔孟之道、借马列主义之皮、执秦始皇之法的中国历史上最大的封建暴君。"《纪要》制定的策略是"打着b52(毛泽东)旗号打击b52力量。""利用上层集会一网打尽";或"先斩爪牙,既成事实,迫b52就范";或"利用特种手段如毒气、细菌武器、轰炸、五四三(一种导弹代号)、车祸、暗杀、绑架、城市游击小分队"杀害毛泽东。 但是由于毛泽东早有警觉,改变了行程,他们的阴谋未能得逞。 毛泽东于1971年9月12日回到北京后,林彪携叶群、林立果于13日凌晨自北戴河仓惶外逃,所乘飞机在外蒙古的温都尔汗地区野外迫降时爆炸身亡。 "9·13事件"从客观上宣告了"文化大革命"的失败及其理论的破产。对毛泽东可以说是当头一棒!然而,毛泽东是从来没有认过输的,一直到1976年9月9日他去世。 据张玉凤的回忆说:毛主席在1976年的4月至7月中旬,思维还算正常。在这段时间里,曾多次就身后党政军领导班子作过"圈划",但也无定论。主席主要是忧虑政局会有剧变。据张玉凤说,毛泽东主席4月份第一次圈定的政治局常委中,共有5人。他们是:毛远新、华国锋、江青、陈锡联、纪登奎"。(笔者认为:华、陈、纪只是用来保驾护航,意在让江青、毛远新接班) 有关这一次"圈定"情况的会议记录人是毛远新和张玉凤。张玉凤坚称,这些"都有记录资料"为证。 那么毛泽东第二次"圈定"政治局常委名单是什么时候呢?据张玉凤回忆,具体时间是在1976年的7月15日。这一次,毛泽东召见了毛远新、华国锋、江青、汪东兴和张玉凤,提出他去世后的政治局常委班子名单及顺序是:毛远新、华国锋、江青、陈锡联、纪登奎、汪东兴、张玉凤等7人。(笔者:这次增加了汪东兴、张玉凤二人。张玉凤时年32岁,因侍奉毛泽东有功,当上了政治局常委,可谓一步登天!) 这一次的谈话记录人多了一个,除毛远新、张玉凤外,还有的一位是本就是中央政治局委员的警卫局局长汪东兴。 张玉凤回忆说:听了毛泽东的这种安排,江青很有些讷闷,要主席再重复一次。江青问:"洪文、春桥呢?"主席当即指着江青说:"你好幼稚!"毛泽东举手往左右方各斩一刀,说:"老帅(叶剑英),王(洪文)、张(春桥)都不进!" 有关这一次的"召见"如果是真的,其人选"安排",一定是出乎于汪东兴的想像的。那么,政治局常委新增人选他汪东兴就是与张玉凤同时"进入"的,这几乎有些匪夷所思,注定会贻笑于世。也许仅仅是因为这个原因,汪东兴一直没有将这一段的记录交出来过,在他的回忆录里也从来没有提及过。 汪东兴不但自己没有出示过这一次"议话"的记录,据张玉凤讲:1976年抓捕"四人帮"后,汪东兴曾以党中央的名义,命令张玉凤将此记录交出,并不准对外透露主席对中央领导的评价。张玉凤声称:该记录已毁掉了。" 。。笔者认为:毛泽东联合林彪之目的是要搞文化大革命打倒刘少奇。选林彪做接班人并写入党章意在表明对林的信任,希望他能把接班人第三棒交给江青。可没想到林彪却大树特树自己的儿子林立果,搞家天下...岂有此理!分道扬镳是注定了的。 。。毛泽东不当党主席,想当国家主席是假,是逼林彪下台设下的一个圈套-林彪、陈伯达等却浑然不知-这正是毛泽东高人一筹的精笔!好不容易才打倒刘少奇,毛不可能再设国家主席,一国岂容二日?让江青当党的主席,张春桥当总理,王洪文当委员长,第四棒让毛远新接班-这才是毛泽东的真实意图。 1956年9月中共"八大"在北京举行,毛泽东当选为党主席,刘少奇、朱德、周恩来、陈云为副主席,邓小平为总书记。他们6人同时为政治局常委。这是一次划时代意义的大会。 "四人帮"倒台后,毛泽东的老战友陈云是这样评价毛泽东的: 陈云曾经与胡乔木谈过以下几点意见。他说: 毛主席的错误问题,主要讲他的"破坏民主集中制,凌驾于党之上,一意孤行,打击同他意见不同的人"。 毛泽东"建党他有份,建国他有功,治国他无能,文革他有罪"。 陈云还向大家做了解释。他说:"如果说中国共产党是毛泽东缔造的,那么李大钊和陈独秀的地位怎么说?所以只能说他有份。在座的建国都有功,但只不过没有他的功劳大。二战结束后,日本比我们还困难,可短短十几年,日本一跃成为世界经济强国,而我们整天搞阶级斗争,政治运动没完没了,把国民经济搞到崩溃的边缘,这是不是治国无能?我们在抗日战争和解放战争中,死于战场的高级将领只有左权同志一人,可大家想一想,在文化大革命中单单省部级以上领导干部被整死的有多少人呢?毛主席亲自发动和领导文化大革命是不是有罪呢?"众人鼓掌三分钟,以示赞同。


全国的大学生朋友们,我们是初升的太阳,是国家民族未来的希望,在这风华正茂的年纪里享受青春带给我们的所有快乐,然而在艾滋病流行的20余年中随着感染和发病人数的增加,有越来越多的青少年生活在艾滋病的阴影下。在全球新增的感染者中,年龄在15-24岁之间的人数超过一半,在我国目前报告的艾滋病感染者中也有相当高比例的青少年。说到这里,我相信大家一定会凝住笑容想到数字背后鲜活而年轻的生命,并开始思考自己对预防艾滋病所应当承担的责任。 青少年是受艾滋病威胁的主要人群,更是迎战艾滋病的生力军,抵御艾滋病的希望就在我们的手中。作为参加全国大学生预防艾滋病宣传教育活动的志愿者代表,我们热切地向全国的大学生,向全国的青少年朋友们发出预防艾滋病共建美好校园的倡议: 1、好学求知,珍惜生命。我们要主动学习预防艾滋病的知识,全面了解相关信息,掌握自我保护的技能,在性、毒品做出正确的决定,保护自己远离艾滋。 2、互助友爱,恭身实践。我们树立社会责任意识,将掌握的知识、技能与同学朋友和家人分享,向社会进行广泛的宣传,做艾滋病防治知识的传播者,以自身的经验积极影响同龄人的态度和行为,减少无知造成的恐惧和歧视,营造理解、宽容、健康的社会环境。预防艾滋病任重道远,同学们,青少年朋友们,让我们奉献出我们的热情与青春,用心参与防艾宣传志愿者活动,从我做起,从点滴做起,从现在做起,让我们手挽手肩并肩共筑预防艾滋病的坚固长城,预防艾滋病在中国的蔓延,志愿者们行动起来吧,为红丝带添一抹亮彩,让红丝带在校园的上空高高飘扬。


侵犯软件著作权虽然是打击软件侵权的有力手段,但在实践中存在诸多困难,怎么理解这些困难呢,主要从以下几个方面着手:1、公安机关在一定程度上不愿意处理这类案件公安机关对侵犯软件著作权罪的行为的严重性,存在着认识上的偏差,更大的注意力放在有重大社会反响的刑事案件上,尤其放在传统的杀人、强奸、抢劫等严重侵犯公民生命财产安全和社会安定的案件上。对杀人、强奸、抢劫等严重犯罪给以足够的重视,在任何一个社会都是非常必要的,因为它直接关系到我们每一个人的安宁。但是社会对侵犯软件著作权罪行为的容忍度是出奇的高,办不好也不会招来舆论的谴责和社会的压力,更不会影响官员的升迁。但这并不意味着就可以对其他的非暴力的案件不给以应有的重视。而且公安机关本身不懂软件代码,在处理这类案件时,主观心理上存在排斥情绪,这是侵犯软件著作权罪立案难的主观原因。2、涉及相关法律问题和技术问题多由于侵犯软件著作权罪证据收集的专业性、技术性较强,不仅软件代码问题,还涉及到制造侵权复制品的技术手段、设备设施的技术性能等方面。对于这些方面,我们普通的社会大众很难把握这些技术难题,即使是我们专业的侦查人员,在进行证据收集、电脑代码查封时,也未必能够很清楚地确认,出现在查封现场的代码究竟是什么代码,在侵犯软件著作权罪案件中,这些代码起什么作用。因此,涉及相关法律问题和技术问题多,这是侵犯软件著作权罪证据收集难的主要原因。3、新型网络的兴起,导致侵犯软件著作权罪形式多样在数字化、虚拟化的网络空间中,侵犯软件著作权罪案件的犯罪主体可以在不同的地点、不同的时间进行犯罪活动,这给案件的侦破、取证等工作带来了地理、技术上的困难。公安机关在侦破这些案件时,通常要花费比传统案件更多的精力,新型网络的兴起已经是时代的趋势,这是侵犯软件著作权罪证据收集难的背景因素。4、追查销售网络难侵犯软件著作权罪案件的犯罪线索主要来源于以下几种情况:公安机关经常通过公开查缉;被害人报案;知情人检举揭发以及工商行政管理部门;文化监察部门的案件移送等方式获取案源等方式。在针对侵犯软件著作权罪立案时,往往只涉及到侵权复制品的销售环节,但是侵犯著作权罪案件并不仅仅限于侵权复制品的销售环节,而要经过整个复制、发行、销售等环节,因此,只有查清侵权复制品所有的制作地点、储存地点和销售地点,才能查明全部案件事实真相,真正实现对侵犯软件著作权罪犯罪行为的打击。追查销售网络难,这是侵犯软件著作权罪证据收集的另一难点。综上,侵犯软件著作权罪在实践中主要存在的困难,基本上围绕上述几个方面理解,可以更清楚地知道困难产生的原因以及后续解决方法:公安机关在一定程度上不愿意处理这类案件、涉及相关法律问题和技术问题多、新型网络的兴起,导致侵犯软件著作权罪形式多样、追查销售网络难。


刘高锋律师北京西城故意毁坏财物罪辩护律师排名要构成税罪须具备两个条件:(1)主观上有税的故意;(2)客观上造成了税收的损失。那么,此案中的甲某是否符合以上两个条件呢律师经过多方调查、取证,认为上述两点甲某均不符合。首先,甲某被提请审查起诉时,工程尚未竣工,根据税务总局的相关规定,房地产开发企业在开发产品完工之前,其所发生的应额尚不能确定。a公司即使在财务上出现错误,并不影响其在工程完工之后,按正确的应税额向申报并缴纳所得税。因此,在工程完工之前并没有造成税收的损失,更无法认定甲某具备税的故意。其次,a公司所列支的270万元,是其应该给c公司的建筑安装工程款,由于b公司是牵头单位,该款须由b公司转付给c公司,所以,那270万元完全可以列支成本。综上所述,不管是主观方面还是客观方面,甲某都不符合税罪的构成要件。检察院采纳了本所律师的意见,对甲某作出了不起诉的决定。刘高锋律师擅长于、民商事诉讼代理及非诉讼业务。诉讼策略丰富,在整个诉讼程序中能够熟练运用各类技巧来争取胜利机会。针对误判案件知道启动审判监督程序积极维权,并在代理案件中积累了许多成功的经验。在非诉讼及法律顾问业务方面,特别针对企业改制、公司和兼并收购、资产重组、技术及产权交易、投资预测以及如何防范经营风险、知识产权保护、债权损害等方面进行了深入细致的研究并成功为企业出具了若干法律意见书。请非法经营罪辩护律师电话咨询刑罚内容量刑是人民法院刑罚裁量活动。因此,量刑是以具有一定的自由裁量权为前提的。我国刑法对于具体犯罪一般都规定了相对确定的法定刑,从而为人民法院根据案件的具体情况正确地裁量刑罚留下了法律空间。因此,量刑主要包括以下内容:决定是否判处刑罚犯罪以后,根据有罪必罚的原则,一般都须判处刑罚。但在我国刑法中存在免予刑事处罚的制度,根据刑法第37条的规定,对于犯罪情节轻微不需要判处刑罚的,可以免予刑事处罚。而且,我国刑法中还有免除处罚的规定,对于具有某种情节的犯罪人应当或者可以免除刑罚处罚。因此,决定是否判处刑罚是量刑的重要内容之一。没有情节或者重大立功表现或者嫌疑人有精神类疾病等一些需要考虑减刑或免刑的情况,那就是直接按量刑来了。量刑量刑,又称刑罚裁量,是指根据刑法规定,在认定犯罪的基础上,对犯罪人是否判处刑罚,判处何种刑罚以及判处多重刑罚的确定与裁量。特征(一)量刑的主体是人民法院量刑权是刑罚权的重要内容之一,也是人民法院的刑事审判权的题中应有之义,当然应由人民法院行使,其他任何、团体或者个人都没有量刑权。因此,量刑的主体是人民法院。刘高锋律师具有坚实的法律理论功底,经过多年的法律实践,凭着深厚的法律功底,丰富的实战经验,娴熟的办案技巧,特别是强烈的正义感和社会责任感,以"专注专业铸就卓越品牌"为执业原则,赢得了广大客户的良好口碑和充分信赖。在行业内及北京法律界具有一定影响力,该律师成功办理过大量的、民事诉讼案件和法律顾问业务,积累了丰富的诉讼和非诉讼业务实践经验。尤其擅长办理各类案件以及公司法律事务、劳动争议、债权债务、交通事故、婚姻家庭等法律业务。北京西城故意毁坏财物罪辩护律师排名3、非法言词证据排除原则言词证据是指以人的语言表述为存在和表现形式的证据。在法定的证据种类中,证人证言、被害人陈述、被告人供述以及鉴定结论都属于言词证据。当代各国刑事证据法普遍禁止将采取刑讯逼供、威胁、、欺骗等方法非法获取的口供作为证据使用,我国刑诉法第43条和《解释》第61条明文禁止了以非法手段收集证据,并明确了非法取得的证言、被害人陈述和被告人供述不能作为定案的依据。以上就是本法律网站小编为大家整理的相关资料。综上所述,我们可以了解到教唆罪的行为人必须是了解自己在做什么,并且对被教唆人实施教唆的情况,法院可以根据情节决定从轻处罚或者是减轻处罚。如还有其他疑问想找律师咨询的,欢迎在线咨询。数罪并罚是刑法中规定对一人犯数罪的情况下的一种量刑情节,对于数罪并罚的,分先减后并和先并后减两种,要区分不同情况分别适用。刘高锋律师工作多年来,先后办理重大经济纠纷、债权债务、辩护、房地产纠纷、商务合同、公司债务、交通事故、工伤事故、离婚析产、遗产继承等案件。可谓身经百战、经验丰富。担任过企事业单位的法律顾问。在劳动法、法律也有着深入、系统的研究。曾承办或参与经办经济、民事、和行政等诉讼和非诉讼案件,案由涉及买卖、担保、股份转让等合同纠纷,人身损害、名誉损害等侵权纠纷,欠薪、工伤等劳动争议纠纷,具有准确的分析能力和丰富的代理经验。以上就是我国和盗窃罪相关的法律法规立对于盗窃超市物品怎样定罪的相关规定了,可以看出来,盗窃罪的判处是以盗窃金额的大小来决定的。如果对于盗窃罪的其他方面问题还不清楚的话,建议去咨询一下专业律师。本法律网站也提供律师在线咨询服务,欢迎您进行法律咨询。延伸阅读:盗窃罪判几年盗窃罪怎么处罚量刑标准盗窃罪量刑标准数额3.教唆未遂的刑事责任原则。根据刑法第29条第2款的规定,如果被教唆的人没有犯被教唆的罪,对于教唆犯,可以从轻或者减轻处罚。教唆未遂是指被教唆者没有犯被教唆的罪而使教唆行为未遂的情况。需要注意的是,这种情况下的教唆犯属于的教唆犯,而非共同犯罪的教唆犯。"被教唆的人没有犯被教唆的罪"具体包括以下情形:(1)被教唆人拒绝了被教唆人的教唆。(2)被教唆人当时接受了教唆犯的教唆,但实际上没有进行任何犯罪活动。如果被教唆人哪怕是实施了犯罪预备行为,也不属于"没有犯被教唆的罪"。(3)被教唆人当时答应实施教唆人所教唆的犯罪,但实际上实施了其他犯罪。(4)教唆犯对被教唆人进行教唆时,被教唆人已经有实施该罪的决意。即被教唆人的犯疑并非教唆者引起。该种情形下的教唆犯的刑事责任原则是"可以从轻或者减轻处罚",需要注意的是:第1,这种情形下的教唆犯是采取得减主义,即是"可以"从轻或者减轻处罚而不是"应当"从轻或者减轻处罚。即是予以从宽处罚还是不予以从宽处罚,由审判人员根据具体的案情裁量。第二,具体是适用"从轻处罚"原则还是适用"减轻处罚"原则,也应由审判人员根据案件的具体情况决定。


自诞生以来,人工智能在世界范围内就引发了轰轰烈烈的研发热潮。由于强大的运算能力和卓越的智能化系统功能,人工智能在人类生活当中开始占据越来越重要的角色地位,而这也使得世界各国开始加大对于新ai技术的开发和提升。事实证明,在短短几十年时间里,科学界对于人工智能的探索已经取得了令人瞩目的成果。从每秒钟运算30万次加法的艾尼阿克,到后来每秒钟都可以进行超过40万亿次加法的"tera_10";从只会抓举小型积木的简单机器人,到后来击败人类棋王的"深蓝",整个人工智能学科的高速进步,不光为本学科带来了翻天覆地的变化,同时也在深深地影响着人类生活。可以预见的是,在目前世界各国都全力支持推动人工智能发展的大背景下,将会有更多性能卓越的人工智能体被研发出来,走进千家万户。毋庸置疑的是,世界各国正在寻求智能化更高、运行速度更快的计算机系统。这样做的结果是显而易见的,更高级别的智能系统会给使用者创造更为客观的社会财富,但与此同时,急速膨胀的人工智能体系是否也应该引起人类的警觉呢?1939年10月的一天,美国艾奥瓦大学的一所实验室里笑声不断,而此时和同伴谈笑风生的约翰·文森特·阿塔纳索夫教授还没有意识到眼前这台笨拙的机器将会对人类社会带来翻天覆地的变化。他和助手-研究生克利福德·贝理给这台机器起了一个粗糙的名字:abc,即两人姓氏的首字母"a"和"b",外加"comp ter"的"c"。而这台当时还没有引起过多关注的"abc"机器,也就是后来各代先进计算机的雏形。受制于时代的限制,阿塔纳索夫和贝理并没有高度重视起自己这一项伟大的发明,"abc"也只是做一些数学方程式的解算。几年之后,美国当局也被卷入了世界大战的旋涡,阿塔纳索夫和贝理都放下了手中所有的学术研究,转而投向国防、武器制造等方面,而"abc"的进一步精研,也就这样被搁置了。到1946年,世界战争进入白热化阶段,美国社会各阶层都不约而同地通过缩减开支来援助政府,爱荷华大学的教育经费也大量停减。在这样一个时代背景下,"abc"的部分零部件都被拆除移作他用了,只剩下存储装置还孤零零地留在原地。


"留学预科"这个词随着留学大时代的到来,家长和学生已经不陌生了,留学预科不仅是一些英联邦国家的要求,读留学预科还可以让学生进入大学前更好的过渡。因此,越来越多的家长选择的出国前先读留学预科。那么,国内外的留学预科有哪些差别呢?下面西外留学预科专家就给大家从三方面介绍一下。 一、师资 很明显,出国留学学生面对的肯定是外教,但是国内预科却不尽然,许多没有办学资质或者不正规合作项目为名的预科是无法提供外教教学或者无法保证学生全程接受外教授课,如果选择了这样的预科项目不仅不能起到为国外生活学习的过渡作用。所以,寻找正规的、大学授权的预科是相当重要的一点。 二、课外辅导 直接去国外读预科,接受的是纯西方的教育方式,教师上完课就走,业余每周会有少数的助教辅导课,针对英语程度极强的学生以及适应能力非常好的学生直接接受这样的教育是完全没有问题的,但是在国内的教育体制下的学生,许多学生存在着"哑巴英语"的现象,高考成绩很高,但是依然说不出流利的口语是普遍现象,这就造成了学生在初到国外学习时遇到了很多困难,很多文化课优异的学生因为英语障碍、得不到更多辅导的情况,导致无法考出更优异的成绩,针对直接读国外预科的这一弊端,国外大学的授权国内预科提供了中西式结合的教育模式,除了在授课期间提供最纯正的西式教育,课后更是安排了助教辅导、中教答疑以及重点难点加强辅导,给学生提供了更多的缓冲以及考出考分的机会。 三、生活适应 由于学生年龄偏小,很多从未出过国甚至从未离开过父母身边,这样的学生直接到国外,面临的是学习和生活的双重压力,因为语言、文化、生活习惯的不同,可能造成对学生心里的影响,为了平稳的渡过预科阶段,建议独立性较弱的学生选择正规的国内预科,逐步的实现适应独立生活,适应英语环境,适应全英授课的新的人生阶段。 西安外国语大学系国内西北地区唯一的一所主要外语语种齐全的外国语大学,西安外国语大学出国培训部开设的各类"高中生出国留学"和"大学生出国读研"留学预科项目,可对接美国、加拿大、英国、澳大利亚、新西兰、西班牙、意大利、荷兰、波兰等国知名大学及热门专业。 上述就是关于国内外留学预科的相关信息介绍,准备出国留学的学生可以提前了解一下。


孔子在中国被尊奉为"圣人",流传至今。其实比孔子大约早800年的商朝武丁王时期的宰相傅说,才是我国历史上第一位被尊奉的"圣人"。 傅说(音悦,y e),山西平陆人,我国殷商时期卓越的政治家、军事家、思想家及建筑科学家。他辅佐殷商高宗武丁安邦治国,形成了历史上有名"武丁中兴"的辉煌盛世,并留下了千古不朽的《说命》三篇。 武丁是我国历史上第一位有确切记载的君王,在傅说历时59年的尽心辅佐下,武丁励精图治,天下人丁兴旺,开拓疆土,扩大商朝的版图,使商朝达到鼎盛时期。 高宗武丁尊傅说为"圣人",就是品德最高尚、智慧最高超的人。历史上人们总把他敬之为"圣人"、"天神"、"梦父"及天策星,因此傅说是中国历史上第一位"圣人"。 后人在傅说故里山西平陆县县城东北傅岩山上,修建了傅相祠,每年农历四月初八日傅说诞辰日,都举行隆重的官祭大典。 傅说故里在平陆,海内外傅氏宗亲不仅尊傅说为始祖,而且视平陆为祖地。


2015年中国癌症统计报告显示,在女性特有的肿瘤中,宫颈癌位居第二,仅次于乳腺癌,是最常见的妇科恶性肿瘤。每年新发宫颈癌6万余例,占世界新发总病例数12%;每年因宫颈癌死亡近3万人,占世界总数的11%。目前宫颈癌平均发病年龄由20年前的54岁,提前到45岁。 宫颈癌症状 宫颈癌早期无明显症状,随着病情的发展出现以下症状。 1 不正常的阴道流血 早期多为接触性出血;中晚期为不规则阴道流血。年轻患者也可表现为经期延长、经量增多;老年患者常为绝经后不规则阴道流血。 2 阴道排液 多数患者有阴道排液,液体为白色或血性,可稀薄如水样或米泔状,或有腥臭。晚期患者因癌组织坏死伴感染,可有大量米汤样或脓性恶臭白带。 3 根据癌灶累及范围出现不同继发症状 如尿频、尿急、便秘、下肢肿痛等;癌肿压迫或累及输尿管时,可引起输尿管梗阻、肾盂积水及尿毒症;晚期可有贫血、恶病质等全身衰竭症状。 宫颈癌与高危型hpv 人乳头瘤病毒(h man papilloma vir s,hpv),是常见的性传播感染病原体,主要感染皮肤或粘膜组织的上皮细胞。 hpv现在已知的有100多种分型,根据致癌性,可将其分为高危型和低危型。hpv16,18,31,33,35,39,45,51,52,56,58,59,68,73,82等15种亚型是已经确定的高危型,可导致各种癌症如宫颈癌、阴道癌、阴茎癌、肛门癌、口咽癌等。低危型hpv感染则会导致生殖器疣、复发性呼吸道乳头状瘤病等。 宫颈癌与高危型hpv的持续感染相关,在我国至少70%的宫颈癌是由于感染hpv16、18这两个亚型所致。 除此之外,宫颈癌的发生发展还与性行为过早及多孕多产等多种因素密切相关。 但并不是感染了hpv就一定会发生宫颈癌, 多数hpv感染具有自限性,能自我清除,临床上常无明显症状。 tips 哪些人是hpv持续感染的高危人群? 1、有多个性伴或性乱者。 2、初次性交年龄低的女性。 3、早年分娩、多次分娩及流产者。 4、与高危男子性接触(高危男子指有阴茎癌、前列腺癌或其性伴侣曾患宫颈癌) 5、其男性性伴侣有其他宫颈癌性伴侣的女性。 6、现在或既往有单纯疱疹病毒感染的女性。 7、艾滋病病毒感染的女性。 8、吸烟或被动吸烟、患有妇科炎症长期不愈等。 9、使用免疫抑制剂者 。 宫颈癌的筛查 宫颈癌是目前世界上唯一可以通过筛查进行早期发现的癌症。 1 早期筛查很重要 宫颈癌是一种病毒感染后的疾病,如果能及时发现致癌病毒感染及癌前病变就有望阻止宫颈癌的发生。 2 多久进行一次宫颈癌筛查 专家表示,小于21岁的女性,无论是否开始性生活,因该年龄组宫颈癌的发病率极低,都无需进行筛查;有性生活以后,从21岁开始,就要进行宫颈癌筛查了,一般每年一次宫颈细胞学检查,连续两年均为正常者,可适当延长筛查间隔至3年查一次;高危妇女人群,筛查时间应较短,最好每年筛查一次。 预防宫颈癌的措施 宫颈癌的预防还要 从个人行为入手 ,如注意性生活卫生,避免早婚、早育和多产,及时治疗妇科疾病等。21岁及以上女性即使接种了hpv疫苗,也需要根据医生建议定期参加宫颈癌筛查,早诊早治,及时阻止疾病的发生、发展。由早期病变进展为宫颈癌需要5-10年的时间。定期宫颈筛查可及时发现宫颈早期病变,局部治疗即可阻止其进一步恶变。早期宫颈癌的治愈率高达95%。 hpv疫苗能有效预防宫颈癌等疾病的发生。 hpv疫苗接种后可刺激人体免疫系统产生保护性抗体,从根本上阻断hpv感染,属于宫颈癌防控的一级预防措施,具有较好的保护效果。 有研究显示,对于 16~26 岁未感染过 hpv 的女性, hpv 疫苗对于癌前病变的保护率超过 95% ,在女性疫苗接种率达到 50% 以上的国家,接种前后 hpv16 、 18 感染率下降了 68% , 13-19 岁女孩中生殖器疣发生率下降了 61% 。


为何突然叫停静脉输液 来源:小雨点的博客 编辑:硕和堂 继宝安人民医院之后,深圳福田人民医院也布,从6月1日起,该院将停止门诊成人静脉输液! 有个头疼感冒,就去医院门诊挂个吊瓶?很多人不论大病小病,都想着:去医院输个液就好了。但实际上,如果能靠吃药治好你的病,最好不要选择输液。 今年4月1日,宝安人民医院开始停止门诊成人静脉注射输液,叫停后医院输液量大幅降至20%-30%。 宝安人民医院停止门诊成人患者输液 今日,福田人民医院也宣布,从6月1日起该院也将停止门诊成人静脉输液,成为深圳又一家向抗生素不良用药习惯说"不"的医疗机构。 并不只是深圳的医院,近段时间以来,全国各地纷纷叫停门诊输液。江苏省卫计委更是要求,2016年底前,江苏全省二级以上医院(除儿童医院外)全面停止门诊患者静脉输液。 为何突然叫停静脉输液? "对全民不良用药习惯的警醒" 福田人民医院院长伍贵富称,这一动议源自于对国人"全民大输液"这一不良用药习惯的的警醒。"静脉输液可以短时间内增加血液中的药物浓度,看起来好像立竿见影,但长期滥用给患者带来的医疗风险和经济负担也日益突出。" 《2012年国家药品不良反应监测年度报告》透露,注射剂不良反应率高达56.7%,有些直接导致患者死亡和医疗纠纷。 "能吃药不打针,能打针不输液。治疗手段应与病情相适应。"伍贵富称,这是医学的基本原则之一,过度医疗只会让治疗的副作用激增。 "如果一个患者能在门诊上就解决了问题,那么他就不应该接受输液。"因此,福田人民医院决定取消门诊输液,"这符合医学原则,同时也能遏制过度医疗。" 福田人民医院还出台了史上最严厉惩罚措施:对出现抗生素药物超常等不合理处方3次以上且无正当理由的医师提出警示,警示后仍出现不合理处方且无正当理由的,暂停其处方权1个月。门诊医师违反规定3次以上,暂停其处方权1个月。 另一家叫停门诊输液的宝安人民医院,南都记者了解到,4月1日之前该院日均输液量达200-300例。4月1日起停止门诊成人患者静脉输液后,宝安区人民医院急诊科的成人输液大厅大部分座位空置。这与深圳市部分医院输液量日均500~1000人次的情况形成了鲜明对比。 作为输液大户的呼吸内科,门诊医生开具的诊疗单几乎都是口服药物。对于病情久治不愈或高热特别严重的患者,医生在进一步诊断后由普通门诊转往急诊,才安排到急诊科输液留观。 据宝安区人民医院介绍,禁令门诊输液在院本部和下辖4家社康中心(海乐、海华、新乐、第五大道)门诊执行,涉及上呼吸道感染、普通感冒、病毒性咽喉炎、无并发症的水痘、流行性腮腺炎、风疹、慢性浅表性胃炎等病种。 宝安区人民医院门诊部主任肖琳解释,停止门诊成人静脉注射输液,是为了解决滥用输液的问题。"虽然很多老百姓认为输液见效快,但是输液存在很多不良反应,例如输液反应、过敏反应等,严重的还会出现过敏性休克危及生命等问题,长期使用静脉抗生素,还会诱发细菌耐药、二重感染等。" 不是不能输液,而是要根据病情来判断 港大深圳医院在2012年开业时就主动放弃了已建好的输液区,不设门诊输液,无论是儿科,还是成人门诊,都看不到吊瓶。 港大医院的全科顾问医生陈志远来自香港,据他介绍,香港一直以来是没有门诊输液的。港大医院除门诊没有输液区外,急诊科也没有专门的输液区,而是设有观察区,医生诊断认为确实有需要的门诊患者可在此输液。 同样来自香港的港大医院全科顾问医生吴汉骥也表示,输液是一件很谨慎的事,不输液的一个重要原因是为了防止抗生素的滥用,"发明一种新药需要十年,但一种耐药的细菌产生只需2-3个月,即使要使用抗生素,仍然是口服比较安全。" 输液真的等于一次小手术? 为何提倡减少输液? 南都记者曾经采访过相关科室专家解读。要包括: - 输液不良反应发生率高于其他给药途径 - 2012年注射引起的不良反应事件占56.7%,其中静脉注射给药占53.5%,在过敏性休克导致患者死亡病例中,85%以上为静脉给药 - 输液药物有六成以上属抗生素 宝安人民院呼吸科徐效峰主任医师介绍,老百姓的观念中,普遍存在"感冒发烧挂个水"的错误认识,很多患者将抗生素当作万能药,多数人在感冒时,自行服用抗生素或者要求医生开抗生素,这些都是错误用药。 早在2013年,国家卫生计生委就发布了"合理用药十大核心信息",其中就包括"能口服不肌注,能肌注不输液"的原则,这也是世界卫生组织确定的合理用药原则。事实上,很多疾病根本不需要输液,口服药物后3~7天可以达到同样的治疗效果央视也曾报道:中国人每年输液总量大约是104亿瓶,除以13亿,相当于每人输液8瓶,这远远高于国际平均2.5瓶的水平。而外国人视输液为小手术,澳大利亚人看病基本没有输液的。 我国是抗菌药物使用大国,中国抗菌药物人均使用量是美国的10倍。不仅如此,静脉输注抗菌药物还有潜在的风险。静脉输液是公认的最危险的给药方式。 输液的风险 风险一 毒副作用 滥用抗菌药物,很可能损伤神经系统、肾脏、血液系统。 风险二 过敏反应这种情况多发生在特异性体质的人身上,其表现以过敏性休克最为严重。绝大部分药物都可能引发,其中青霉素最常见也更为严重,严重时甚至可能致命。 风险三 二重感染当用抗菌药物抑制或杀死敏感的细菌后,有些不敏感的细菌或霉菌却继续生长繁殖,造成新的感染。 风险四 耐药由于药物长期刺激,使一部分致病菌产生变异、成为耐药菌株。"超级细菌"很大程度上就是抗菌药物滥用催生出来的。 哪些情况需要输液专家认为只有3种情况才真正需要输液: 1.吞咽困难 2.严重吸收障碍(如呕吐、严重腹泻等) 3.病情危重,发展迅速,药物在组织中宜达到高浓度才能紧急处理的情况安徽省卫计委公布"53种不需要输液"疾病清单:记住:能少用就不多用,能口服不肌注,能肌注不输液! 也有必要说的是,对于安徽省卫计委2014年发出的规范管理静脉输液的通知,也有医生认为,患者个体化差异比较大,不应一刀切,且诊病开药是学术范畴问题,用行政手段来加以限制其实不妥。


一、司法工作人员,即依法具有侦讯、检察、审判和监管人犯职务的人员为贪图钱财、袒护亲友、泄愤报复或者其他私情私利,具有下列行为之一的,应当依照刑法第一百八十八条的规定追究刑事责任:(一)对明知是无罪的人,即没有实施危害社会行为,或者根据刑法第十条规定,情节显著轻微,危害不大,不认为是犯罪以及其他依照刑法规定不负刑事责任的人,采取伪造、隐匿、毁灭证据或者其他隐瞒事实、违背法律的手段,以追究刑事责任为目的进行侦查(合采取强制性措施)、起诉、审判等追诉活动的;(二)对明知是有罪的人,即有确凿事实证明其实施犯罪的人,采取伪造、隐匿、毁灭证据或者其他隐瞒事实、违背法律的手段,故意包庇使其不受侦查(合采取强制性措施)、起诉或者审判;故意包庇不使受追诉的犯罪事实,既可以是全部的犯罪事实,也可以是部分犯罪事实或情节;(三)在审判刑事案件中故意违背事实和法律,枉法进行判决、裁定,使有罪判无罪、无罪判有罪或者重罪轻判、轻罪重判的;(四)故意违背事实真相,违法变更强制措施,或者虽然采取强制措施,但实际放任不管,致使人犯逃避刑事追诉的;(五)对依法不该减刑、假释、暂予监外执行的犯人,询私枉法,予以减刑、假释、暂予监外执行的;(六)在审判民事、经济、行政等案件中,故意歪曲事实,违反法律、询私舞弊,枉法裁判的;(七)司法机关专业技术人员在办案中故意提供虚假材料和意见,或者故意作虚假鉴定,严重影响刑事追诉活动的。二、下列行为,依法应当依照或者比照刑法第一百八十八条的规定追究刑事责任:(一)国家工作人员,无论是否司法工作人员,利用职务包庇、窝藏走私、套汇、投机倒把、重大盗窃、贩毒、受贿等犯罪分子,隐瞒、掩饰其犯罪事实的;(二)对于走私、套汇、投机倒把、重大盗窃、贩毒、受贿和前项规定的犯罪人员,有追究责任的国家工作人员不依法处理的;(三)有查禁卖淫、嫖娼活动职责的国家工作人员,为使犯罪分子逃避处罚,向其通风报信,提供便利的;(四)国家工作人员利用职务,对明知有《关于惩治假冒注册商标犯罪的补充规定》所列犯罪行为的企业事业单位或者个人,故意包庇,使其不受追诉的;对上述补充规定所列犯罪负有追究责任的国家工作人员,不履行法律所规定的追究职责,应当比照刑法第一百八十八条规定追究刑事责任的;(五)国家工作人员利用职务,对明知犯有《关于惩治生产、销售伪劣商品犯罪的决定》所列犯罪行为的企业事业单位或者个人故意包庇使其不受追诉的;负有追究责任的国家工作人员对具有上述决定所列犯罪行为的企业事业单位或者个人,不履行法律规定的追究职责,应当比照刑法第一百八十八条规定追究刑事责任的;(六)专利局工作人员及有关国家工作人员(如专利管理工作人员),询私舞弊,情节严重的;(七)其他法律明确规定应当依照或者比照询私舞弊罪追究刑事责任的。三、为牟取单位或小集体不当利益而实施第一、二条行为的,依法追究直接负责的主管人员和其他直接责任人员的刑事责任。四、要严格掌握法律规定各种询私舞弊行为的构成条件和情节。 确定依法追究询私舞弊犯罪者的刑事责任,要综合考虑行为给国家、社会和人民利益造成的损失,给有关当事人的生命、人身、财产等方面的权益造成的损失,以及造成的政治影响等方面的情况。情节显著轻微、危害不大的,不应以拘私舞弊罪追究刑事责任。对于由于认识水平、工作能力而造成错案,不应以询私舞弊罪论处。由于隶属关系,不得不执行上级错误指令,造成错案,如果不具有询私舞弊的共同故意和行为,也不能以佝私舞弊罪追究刑事责任。五、与司法工作人员或法律明确规定依照或比照刑法第一百八十八条规定追究刑事责任的人员勾结,伙同进行本解释所列犯罪行为,以共犯追究刑事责任。六、犯拘私舞弊罪并有受贿、刑讯逼供等行为构成犯罪的,应当依法按数罪并罚原则追究刑事责任。七、本解释发布后办理的拘私舞弊犯罪案件,按本解释办理。本解释发布前已按法律规定处理过的案件,不再变动。


秦岭-淮河线是中国(特别是东部)南方和北方的地理分界线,此线的南面和北面,无论是自然条件、农业生产方式,还是地理风貌或是人民的生活习俗,都有明显的不同。不过,对于秦岭、淮河一线附近的城市,往往呈现出南北文化、习俗、自然环境等交融的特点。比如安徽省的蚌埠市,淮河从该城市穿过。而对于河南省最南端的地级市-信阳市,因为地处淮河附近,也被誉为"江南北国、北国江南"。 一 首先,信阳作为河南省地级市。位于河南省东南部、淮河上游。东连安徽,南接湖北,为三省通衢,是江淮河汉间的战略要地,鄂豫皖区域性中心城市。在中国古代历史上,信阳古称义阳、申州,又名申城,被誉为山水茶都。对于信阳地区,楚文化与中原文化在这里交融,形成了信阳独特的人文环境。同时,信阳是全国唯一连续八年入选中国十佳宜居城市的城市,荣获中国优秀旅游城市、国家园林城市、中国最具幸福感城市、中国最美城市等头衔。 二 目前,信阳面积平方公里,人口869.77万人,下辖浉河区、平桥区、潢川县、淮滨县、息县、新县、商城县、罗山县、光山县这2区7县。其中,就信阳市下辖的息县来说,在名气上甚至要比信阳市要大。在中国古代历史上,息县不仅是最早设置的县之一,而且2700年没有变过名字,被誉为"天下第一县"。具体来说,早在公元前682年,也即历史上的春秋时期,楚国开始陆续吞并周边的小国。其中,楚国在消灭息国,就地设置息县。息夫人闻讯后,想投井自杀,但遭斗丹劝阻作罢。息夫人为保全息侯的性命,无奈嫁给楚文王。 三 到了西汉时期,息县被改名新息县,历东汉、魏、晋、南北朝均属汝南郡(国)。西晋建立后,新息县为汝南国治。北周时改置息州,均为州郡治所在地。公元607年,隋朝废息州为汝南郡,新息县属之。公元621年,唐朝以县置息州,后变为息县,先后为梁、唐、晋、汉、周5个王朝据有。北宋建立后,新息县属蔡州。明朝时期,息县属中都临濠府(后改名凤阳府)。清朝雍正皇帝在位时期,升光州为直隶州,息县属之。 四 最后,1998年6月,撤销信阳地区,改设地级信阳市。息县属之至今未变。截至2013年12月10日,息县辖6个镇、13个乡。目前,息县面积1835平方千米,约为信阳市的十分之一,人口80万左右。在历史文化上,息县的濮公山位于淮河南岸,被宋朝诗人苏东坡誉为"东南第一峰"。此外,息县境内有古息国故城遗址、秦楼遗址、赖国故城遗址等数十处省、地、县文物保护单位。 综合网络,如有侵权联系删除。


晚上睡不着,早上起不来,靠着咖啡撑过工作日。 六点起床赶车,下班已经天黑,回家后刷刷手机、玩玩游戏,再一看表已经半夜了。 这是一个"夜猫子"越来越多的时代,"报复性熬夜"的概念也在悄然盛行。 所谓"报复性熬夜",是指白天过得不满足,便想在夜晚找到补偿,哪怕工作劳累,回家很困,也执着的要撑到实在睁不开眼了再睡。 为何年轻人纷纷"报复性熬夜"?按照人体健康的需要,一个人理想状态下的时间分配,大致是工作八小时,睡觉八小时,剩余的八小时是休闲和学习的时间。但在实际生活中,工作超支了大部分时间,不少年轻人只得去向睡觉索要时间满足休闲和学习的需要。 睡得晚、起得早,已经越来越成为年轻人或主动或被动的作息习惯。 3月21日是世界睡眠日。中国睡眠研究会将今年睡眠日的主题定为"健康睡眠益智护脑"。 据中国睡眠研究会2016年公布的睡眠调查结果显示,中国成年人失眠发生率高达38.2%,超过3亿中国人有睡眠障碍,且这个数据仍在逐年攀升中。 《医师协会》发布的《2018年中国90后年轻人睡眠指数研究》显示,90后睡眠时间平均值为7.5小时,低于健康睡眠时间,六成以上觉得睡眠时间不足。其中,31.1%的人属于"晚睡晚起"作息习惯,30.9%的被访者属于"晚睡早起",能保持早睡早起型作息的只占17.5%。 而在另一份报告中,84%的90后存在睡眠困扰,34的"90后"是在晚上11点后入睡,13是在凌晨1点入睡。90后比老年人面临更加严重的睡眠问题! 缺觉"的危害有多大? 从健康角度看,长期睡眠不足的人患抑郁症、焦虑症、自杀等风险是普通人的1.4倍以上。从经济角度,睡眠不足,也难以保证工作效率。 2017年,日本政府发布的一份有关"过劳死"的白皮书显示,将近一半的全职工人表示自己没有充足的睡眠,而加班是造成睡眠不足的主要原因。欧盟要求每一天中必须有连续11个小时的停工期,但日本没有管理最少休息期的法规。 美国研究机构兰德公司的一项报告显示,睡眠不足导致日本经济每年损失多达1380亿美元,约为国内生产总值的2.9%。该报告说,将夜间睡眠时间从不足6小时增加到6到7小时,就可能让日本经济增加757亿美元。


咸丰自1860年9月逃到承德避暑山庄以来,无时无刻不在倾听北京的消息,但首先传来的消息却令他肝胆欲碎:英法火烧圆明园,使他所代表的清王朝威严扫地,并给整个中华民族留下了耻辱的一页。咸丰本不是一个能挽狂澜于即倒的一代君王,面对内外交困,支离破碎的旧山河,他似乎已没有了当年的锐气和勇气,在肃顺等人的纵容下,反而采取了破罐子破摔的做法,索性不理朝政,每日就是听戏,看戏,纵情声色,使咸丰本已十分展弱的身体更加不堪,直到每日里经常咳嗽、吐血。咸丰的六弟、恭亲王奕诉代表咸丰在北京与英、法、美俄分别签订了条约,使得大清王朝暂时度过了眼前的危机。咸丰接到奕诉请求皇上早日还宫的奏折后,本欲马上回北京,以安定人心,安定天下。肃顺等人怕咸丰回京后,对自己的倚重会下降许多,便极力阻止咸丰回京,这样,咸丰就在承德长住了下来。1861年春,咸丰的病情开始加重,有些大臣的奏折就叫懿贵妃替他批示,这为她从政拉开了序幕,但也招来了重大危害,险些酿成杀身之祸。 肃顺作为政坛老臣,对懿贵妃的举动是非常敏感的,他十分清楚地意识到这个女人将是他政治上的死敌,必先早日除之而后快,若待她成了气候,树大根深,只怕自己是凶多吉少,因此,他劝咸丰说:懿贵妃恃子而骄,居心叵测,皇后忠厚老实,将来恐怕奈何不了她。他对成丰效仿汉武帝杀钩弋夫人,及早除掉已初露端倪的懿贵妃。钩弋,姓赵,汉武帝夫人,因居钩弋宫故名。钩弋夫人生昭帝。在昭帝将立为太子时,汉武帝唯恐钩弋夫人以后恃子专权,乃赐其死。咸丰也是非常害怕自己死后出现吕后、武则天这样的人物,搅得大清王朝不得安宁,但杀掉懿贵妃,他又不忍心,一则过去情意绵绵,共渡过许多美好时光,二则自己一直以"仁""孝"处世,怕杀了懿贵妃,于自己名声有亏,思前想后,最终还是放弃了杀懿贵妃的想法。但这件事最终还是传到了懿贵妃耳朵里,所以她上台后的第一件事,就是毫不留情地坚决处死肃顺。咸丰十一年(1861年)农历六月初九,是咸丰三十一岁生日,也是他人生最后一个生日,在生日宴席看戏的时候,咸丰病情加重,戏没看完,就因腹痛难忍而中途退场。咸丰十一年七月十六日(1861 年8月21日),咸丰病危,在几经昏迷之后,他清醒过来,他知道这是留给他人生的最后一点时光了,他命肃顺念早已写好的圣旨:立皇长子载淳为皇太子。接着又命肃顺念第二道圣旨:"皇长子载淳现为皇太子,着派载垣、端华、景寿、肃顺、穆荫、匡源、杜翰、焦祐瀛尽心辅弼,赞襄一切政务。特谕。"咸丰见肃顺念完圣旨,又对载淳说:你也认一认我所托付的八大臣,给他们作个揖吧!载淳代表顾命八大臣辞谢,咸丰不许。最后,顾命八大臣站成一排,与载淳相向而立。一面作揖,一面跪下还礼,这样咸丰就完成了他的托孤仪式。待大臣们跪安退出后,咸丰又叫来皇后钮祜禄氏,并交给她一枚长方小玉印,上面刻着"御赏"二字,随印还有一张黄纸,上面用朱笔书写着一行字: 某如实子为帝,骄纵不法,卿即可按祖宗家法治之。特谕。据民间传说,咸丰临死前将"同道堂" 汉玉印交给懿贵妃,并叮嘱她一定要尊敬皇后。咸丰十一年七月十七日寅时(1861 年8月22日),咸丰病死热河,享年三十一岁。咸丰死后庙号"文宗"。咸丰在位的11年中,没有过一天轻松的日子,咸丰刚继位就发生了太平天国起义,接着又发生了第二次鸦片战争,直到他死的时候,天下局势仍然大乱。内忧外患使他愤懑、无策,寄情于声色也松弛不了高度紧张的神经。临终前他颇费心机留下了两权制约的机制,以图确保年幼的皇子顺利登基。但谋事在人,成事在天,最终,随着慈禧辛西政变的成功,一个统治中国近五十年的女人开始出场了。


致2020年cpa零基础考生: 2020年伊始,一场突如其来的新冠疫情,打破了各行各业的原有节奏,行业发展低迷、大量裁员迫对身于职场或即将踏入职场的你犹如饿虎拦截。疫情影响下,迫使更多的人开始重新思考和定位未来的职业规划。因此,作为各大事务所、企业"黄金敲门砖"的cpa证书成为了众人眼中的不二选择。尤其很大一部分是零基础小白群体,亦看到了cpa的价值所在,也纷纷进入到备考大军队伍中来。 如果说,疫情下职场重新格式化,是一种战略的"被选择",那么,职场形势风向标下的"价值",则需"主动出击"! 2020年什么样的人能站起来?一定是富含高价值竞争者! 你只有富含高净值能量,你才有存在的价值! 2020年是机会最好的一年!将是无数会计人改变命运的绝佳之年! 2020年注册会计师统一考试报名已进入倒计时阶段,据相关数据显示,今年预计有超过200万考生报考cpa!在历史新高人数的重压之下,体现出了富含高价值cpa的新机遇,但同时,大量涌入者势必会让通向注册会计师的路途更为狭窄,面对如此多的竞争者,尤其是零基础小白该如何脱颖而出?又该采取什么样的学习方法才能保证cpa考试顺利通关呢?结合这几个问题,我们来详细聊聊零基础小白cpa备考路上的逆袭步法。 注册会计师共分为两个阶段,综合阶段和专业阶段,专业阶段又分为六科,而2020年会计、经济法、税法的变化均较大,财务成本管理、审计、公司战略与风险管理基本无实质性变化。接下来我们分别对各个科目详细介绍一下。 (一) 会计 1、制定严格的学习计划 不忘初心,方得始终。我们的目标是顺利通过注册会计师资格考试,为了实现这一目标,必须订立计划,并严格执行计划。就是订立学习时间表,每天学习什么内容,看多少页,复习到什么程度,达到什么要求,自己心中要有数。如果没有计划,三天打鱼,两天晒网,每次看书都只看前几页,到头来只能是竹篮打水一场空,徒劳无获。 2、全面研读大纲和教材,把握教材 考试大纲和教材是命题的重要依据。一般来说,考试大纲和教材包含了命题范围和答案标准,考生必须按考试大纲和教材的相关内容回答试题中的问题,否则很难得高分。会计考试的特点是覆盖面广、系统性强,因此考生要进行全面地、系统地学习,一定不能忽视基础知识。在看书时,要仔细做笔记,把重点、难点、疑点加以归纳总结,从而让厚书变薄,并理解其精华所在。对于考试必考的知识点,如金融工具、长期股权投资、资产减值、债务重组、收入、会计政策变更、会计估计变更、前期差错更正、资产负债表日后事项、企业合并和合并财务报表等内容,考生一定要全面掌握,能够举一反三,做到以不变应万变。 研读教材需要投入一定的时间和精力,考生应合理分配工作和学习时间。强调对教材的研读,是真正理解教材中的重要内容,并不是要求考生把教材的全部内容逐字逐句地背下来,要在理解的基础上掌握教材的内容,要知道为什么,要明白问题的根本,丢了"根",抛了"本","根本"不对!研读教材主要是掌握教材内容的本质及不同章节的内在联系,能够从整体上全面、系统地掌握教材的内容,做到知识的融会贯通。研读教材时,要循序渐进,一步一个脚印,不放过每个环节,并认认真真地做好笔记。对每章节内容,哪些问题应该掌握,哪些内容只作为一般了解,哪些要点要熟练精通,都要做到心中有数。 3、讲究学习方法,善于总结规律,掌握问题的关键点,使复杂问题简单化 教材的很多章节都是根据准则及相关法规编写的,其语言精炼、严密、逻辑性强提高了教材的档次。不过,这也在一定程度上给考生阅读教材带来了难度,因此,考生在研读教材时应注意掌握教材中重点和难点内容的关键点。 2020年教材结构比较特殊,如果按教材顺序自学,基础薄弱的同学可能不易接受,如果结合课件学习,通常会起到事半功倍的效果。 4、不断强化练习 从某种意义上讲,考试就是做题。因此,在平时学习过程中,适当地做一些典型的习题是考试成功必不可少的一个环节。会计涉及的内容十分广泛,仅仅依靠记忆和自身理解是远远不够的,通过做一些典型题目可以更好地掌握教材中的重点内容,逐渐总结出考试的重点与规律,发现自身学习中的薄弱环节,从而不断提高学习成绩。 做习题时一定要做一些典型的习题,如历年的考题。实事求是地说,历年考题最值得研究,当然,考生还应在市场上选择一本较好的习题集进行练习,但资料不宜过多,多了容易导致简单或已经掌握的内容重复练习,重难点不够突出,没有掌握到精髓,反而不利于学习和考试。 在考试时,应保持良好的心态,战胜胆怯心理,仔细阅读试卷,认真作答;做题时,合理分配时间,由易到难,由简到繁,尽量做到会做的题一题不错, 该得的分一分不丢。 (二)经济法 《经济法》科目历年来都会有大幅调整的特点? 经济法与其他科目相比,教材每年都会根据相关法律法规的变化而调整教材内容,有时会有大规模更新,以2020年教材为例,第七章证券法基本上是全新的内容。 备考时如何应对《经济法》每年新变化?学习重点是不是很难把握呢? 1、教材阅读计划 考生无论拥有多少复习资料,教材都具有不可撼动的核心地位。读书的速度按照6页每小时来说的话,读完这本教材需要约90小时。 2、正确对待历年试题 其实,以前年度的真题是最好的备考资料,通过对真题的研究和解题,有助于学员掌握经济法科目的命题规律和命题思路。因此,考生千万不要从网上随便下载以前年度尤其是比较久远年度的真题,因为作为学生,你可能会很难甄别哪些是可以作为参考的,哪些已经不合时宜。 3、建立正确的学习观念 一是紧扣考试大纲、精读教材;二是把握重点,合理安排复习时间;三是如果无法做到准确掌握所有内容时,以及格为底限。 四是制定切实可行的学习计划,循序渐进完成学习目标。 4、复习时间安排 从4月初开始报名、购买教材,到10月考试,一共不到7个月时间,需要进行合理的规划: 4-6月:精读教材。如果每天备考3个小时左右的的话,3个月的时间加起来是90小时,以每小时阅读6页的速度,恰好可以精读完整本教材。 6-7月:巩固拾遗。进行第二轮甚至第三轮复习,拾起漏掉和遗忘的知识点,配合习题练习。 8-9月:强化提高。把近五年真题仔细做,尤其将错题记录成册,把握出题思路,命题规律。 10月:冲刺应试。 5、考场答题技巧 (1)单项选择题: 单选题共有24个小题,每小题1分,一共是24分。单选题有四个选项,其中只有一个选项是正确的。经济法单选题是难度最小的题型,考生应争取再单选上得到20分以上的分数。 (2)多项选择题:多选题一共有14道小题,每题1.5分,共21分。多选题有四个选项,其中有两个或两个以上的正确选项,只有全部选对才能获得分数,错选、漏选均不得分。 多选题难度较大,得分不容易,考生应保证获得10分以上分数。 (3)案例分析题:案例分析题一共四个题目,合计55分。一般前两个题目的分值均为10分,第3个题目的分值为17分,第四个题目分值为18分。其中只有一个题目大家可以选择用中文或英文解答,如果用英文就必须全部用英文,正确可多得5分。从近五年的考试情况看来,案例分析题主要集中于破产法律制度、票据法律制度、合同法律制度(结合物权法律制度)、公司法律制度与证券法律制度相结合的内容。 (三)审计 大多考生都感觉《审计》挺难,对于零基础小白该掌握审计的哪些特点? 1、《审计》科目是目前我国注册会计师专业阶段6门课程考试中难度仅次于《会计》的一门课程;根据中注协提供的及格率信息分析,参加审计科目考试的学员及格率比较低,平均通过率是大约15%-20%左右,在全部科目中居第三位。 2、零基础的同学需要清醒的意识到,审计科目是有相当难度的,正因为有难度才显示其价值所在!对零基础的同学要求要比有基础的同学更高些! 3、需要学习的内容会更多些,比如在正式学习之前最好学习一下审计学的一般原理课程和会计学原理的课程! 4、零基础的同学在《审计》的学习方面需要付出更多的时间、精力! 那学习《审计》采取什么样的学习方法?该注意哪些事项? 1、首先要了解自己的现状与实力-分析自己学习《审计》科目的能力 (1)零基础的现状是对审计一无所知,意味着在学习审计课程的时间,理解课本的内容难度要更大些,对老师讲的内容理解速度要更慢些,可能会产生焦急和烦躁的心态,会怪老师没有讲清楚,其实是自己的知识储备不够,需要提前补审计原理课! (2)零基础的同学还应该知道自己的学习能力如何?如果学习能力很强(记忆力和理解力都比较好,能有自己有效的学习方法、有坚持不懈的努力态度和有坚决的完全执行计划的行动),就算是零基础,也可以学习和理解审计课本的内容,可以复习完审计备考资料,也可以掌握审计的大部分考点,并最终通过考试! (3)如果学习能力本来就不太强的同学,那就需要认识到自己必须要通过付出更多的学习时间、需要更努力、需要更多的总结和思考重点与难点! 2、要学习《审计》,要制定合理可行的学习计划 (1)上审计辅导课之前先安排时间,学习审计学原理的内容,熟悉审计流程和一般方法,熟悉审计思维! (2)每一次上课前,提前学习上年的审计课本和教材的相关内容,笨鸟先飞! (3)要保证时间,参加恒企教育的《审计》辅导班,完成全部环节和各个阶段课程的复习和模拟题练习! (4)零基础学员,尽量每一天都能保证四小时学习审计,报考时需要按照自己的实际情况和条件,少报一两门。 3、摸索和运用适合自己的《审计》学习方法 制定计划-认知听讲-耐心看书-仔细读题-记忆总结-错题积累-理解记忆-循环记忆-思维导图-总结提高 4、学习与复习《审计》科目各阶段应需注意的事项 (1)学习阶段:零基础学员应对记住,千万要坚持参加《审计》直播课各个阶段的学习,没有时间保障不可能自动让知识进入大家的脑袋,不要三天打鱼两天晒网,争取100%参加直播课,要相信"宝剑锋从磨砺出、梅花香自苦寒来",相信只有量变才能有质变! (2)坚持按照我们已经进行一年的教学模块和方式组织《审计》科目的学习。针对基础阶段、教材变动、串讲、模拟试题讲解、押题宝等各个模块分别,结合新的考试大纲和新教材的内容,认知学习和复习,反复学习和熟悉老师讲过的直播课上讲义的主要内容;掌握必考的知识点,提高学习效率。 (3)具体措施:a.课前一定要预习先看看讲义;b.上课认真听讲,不发表与课程无关的话题; c.不懂问题及时提问;d.课后及时总结;e.及时刷题;f.留出复习时间进行复习;j.准备错题本并改正积累错题;h.作模拟题。 (4)各位学员务必要注意对《审计》教材进行认真阅读和总结,特别是坚持对审计科目的每一章内容在学完直播课后都需要进行课后总结或编制思维导图。 (5)可以与其他零基础学员进行互动,交流学习的建议和体会,共同提高。 (6)建议零基础学员学习一些会计基础课程(比如会计学原理、基本的会计报表分析)的辅导,补一下会计基础,不然影响《审计》科目的听课效果,综合题更是难以做好。 (7)学习审计通关宝典的内容,熟悉《审计》科目考试大纲要求的考点; (8)至少全面学习和记忆三遍《审计》科目的教材。 (9)每一章都进行总结,熟悉和掌握每一章中的重要知识点。 (10)多刷模拟题,发现自己的记忆盲点或者漏记、混记和错记的知识点。 (四)税法 《税法》科目考试具备哪些特点? 1、重点章节比较突出 基础四税-准备基础四税,得考试通过-增值税、消费税、企业所得税、个人所得税 难点四税-准备难点四税,得考试必过-关税、资源税、土地增值税、环保税 国际税收-准备国际税收,得考试稳稳必过-国际税收属于老套路考点 较小税种-准备四要素,得考试想不过都难-征税范围、计税依据、税率、税收优惠 2、重点题型比较突出 考试难点在于:计算题与综合题 计算题与综合题主要在于测试: 增值税法、消费税法 、企业所得税法 、个人所得税法、关税、资源税、土地增值税、环保税等。 3、重要考点测试有综合性,在细化的基础上,又有了综合性 准备细化-熟知重点考点-细化税种四大要素 准备综合-会增加干扰项-比方增加免税等优惠 (二)税法的八步学习法 第一步:抓预习-老师讲义提前打出,预习税法体系,预习重要税种-听课有准备 第二步:抓讲义-讲义提前打出,老师讲义是精华-听课有笔记 第三步:抓考点-老师讲义-掌握面-冲刺串讲-掌握点 第四步:抓节点-考点掌握-注重下细节 第五步:抓理解-税法不是要死记硬背,在理解的基础上-准备考点-在听直播基础上-重在理解 第六步:抓记忆-老师上课时的记忆口诀,记忆方法,记忆体系属于必须掌握内容。紧跟直播-当堂记忆 第七步:抓习题-三类题要准备: 1.是真题-知道测试方向 2.是章节题-做到知识点操练-掌握知识点-以题带点 3.是模拟题-起到查漏补缺的效果 做题要注意:(四个做到) 一要做到:检验自己,通过做题来检验自己对知识的掌握程度,超缺补漏,强化自己 二要做到:切忌题海战术,做题的过程要学会总结,学会分析 三要做到:通过做题掌握易错点-错在哪里,为什么错,如何纠正 四要做到:通过做题来提高熟练程度-掌握细节 第八步:抓押题-老师押题的内容-往往考试比较到位-建议先按老师思路准备 大家不要盲目押题 (五)财管 《财管》科目考试具备哪些特点? 财管考试重在计算,整张试卷有90%以上的题目是需要计算的,田老师提出要过财管,就必须"多做计算题,反复做同一道题目"。财务管理是精细化量化管理,因此必须以计算作为学习的重点,光听懂财管是无法通过财管的。计算题除了在主观题出现,客观题同样大部分是计算题,真所谓得计算题者得财管。 那零基础又该怎么学习《财管》呢? 零基础并不代表您一点基础没有,只要您学过初中数学,就可以来咱们这儿学财管,现在很多学员就是这样的背景,他们学得很嗨;其次,学习要找准方向、掌握方法。努力固然对咱们通过注会很重要,但方法方向更重要 首先,零基础学员只要把老师当作值得信赖的引路人,就可放心大胆去学;要坚持重复的力量,通过反复去训练经典的历年真题,把握命题思路,掌握财管公式的运用,熟能生巧。经典的题目,如企业价值评估、投资项目决策,产品成本计算等必须在有限的几道经典题目上反复训练,不断总结。同一道题目做三遍、五遍甚至十遍都不为过。咱们最终的目的是形成对这些题目的肌肉记忆。只有这样,才能在时间紧迫的考场上多拿分,增加通过财管考试的"安全边际"。但要注意的是,"多做计算题"并不是要咱们搞题海战术,这是很多考生陷入的误区。 最后,也是最最关键的是信心。田老师经常对学员说,"财管虐我千百遍,我待财管如初恋",只要满怀热情、满怀信念、满怀对未来美好生活的追求,无论您是零基础还是有基础,最终都会通过财管考试! (六)公司战略与风险管理 注册会计师考试中,战略难度相对较低,只要保持良好学习惯基本上问题不大,结合诸多考生的学习习惯,我们先来分析一下考生学习习惯都有哪些? 1、学习习惯 (1)总是站在系统的高度把握知识 很多考生在学习中习惯跟着老师一节一节地走,一章-章地学,不太注意章节与学科整体系统之间的关系,只见树木,不见森林。随着时间推移,所学知识不断增加,就会感到内容繁杂、头绪不清、记忆负担加重。事实上,任何一门学科都有自身的知识结构系统,学习一门学科前,首先应了解这一系统,从整体上把握知识,学习每一部分内容都要弄清其在整体系统中的位置,这样做往往使所学知识更容易把握。 2.追根溯源,寻求事物之间的内在联系 如何学好这门课程,怎样复习才能顺利掌握并通过这门课程。从总体上讲,任何一门课程的学习都是一样的,就是要把书本的基础知识学透、学活,在头脑中形成对该门课程清晰的知识体系和脉络,不要死记硬背,而要在理解的基础上掌握知识,活学活用,以不变应万变。 学习的重点是要把知识学活,多做练习题尤其是案例分析,但不能仅停留在记住做过的习题层面上,而要在做过的习题中自我总结,举一反三,活学活用。考试学习最忌死记硬背,重要的是要弄清楚不可 能出现与所做的题一模一样的试题,道理,不论学习什么内容,都要问为什么,这样学到的知识似有源之水,有本之木。即使所提的问题超出了教材上的知识范围,甚至老师也回答不出来,但这并不要紧,重要的是对什么事都要有求知欲、好奇心,这往往是培养我们学习兴趣的重要途径,更重要的是养成这种思考习惯,有利于思维品质的训练。 3.发散思维,养成联想的思维习惯在学习中我们应经常注意新旧知识之间、学科之间、所学内容与生活实际等方面的联系,不要孤立地对待知识,需养成多角度地去思考问题的习惯,有意识地去训练思维的流畅性、灵活性及独创性。知识的学习主要通过思维活动来实现,学习的核心就是思维的核心,知识的掌握固然重要,但更重要的是通过知识的学习提高智力素质,智力素质提高了,知识的学习会变得容易上面讲的学习的三个习惯实质上是三种思维习惯。学习的重点就是学会如何思考。 零基础小白怎么学《战略》? 1.细读教材,夯实基础知识 第2次阅读要结合课程,结合轻-来看教材,一边听课件,,把课程的内容与教材相结合,一章节一章节地去学习,重点、难点都要逐一突破。