The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

#

如果仍然使用缺省的类加载策略:PARENT_FIRST,  由于BSF自身加载类,导致使用org.eclipse.osgi.framework.internal.core.BundleLoader装载器来装载,在这个装载器级别,似乎发现不了JavaScriptEngine类,实际上JavaScriptEngine和BSFManager同在一个包中。

一个可行的解决方法是,将该baf.jar(JavaScriptEngine类所在jar包)拷贝到jre/lib/ext目录下,则org.eclipse.osgi.framework.internal.core.BundleLoader类装载器一定能找到,因为该JDK加载顺序在org.eclipse.osgi.framework.internal.core.BundleLoader之先。

然而,系统管理员处于安全的考虑,不同意在jre下放置bsf.jar包。看来只得另寻他法。通过阅读下面的文章,理解WAS6.1的加载方式,可知创建应用程序共享库可以解决这一问题。参考:在应用程序服务器级别使用共享库。注意:在应用程序级别使用共享库并不能解决这个问题,如果该类没有使用自己的ClassLoader则应可行。

详细操作步骤:

1、打开WAS6.1控制台,创建共享库



2、在应用程序服务器级别使用共享库


新建类装载器,注意,这里选 类已装入且是先使用应用程序装载器 选项

保存

类装载器创建完成

新建共享库的引用

选择已经配置好的共享库

这是配置完的样子





以下为参考文章

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

理解WAS 6.1的类加载(4)

2008-12-3

  12.5.2步骤2:添加一个EJB模块和工具JAR

  下面,往应用程序中添加一个EJB,它也依赖VersionChecker JAR文件。在此,在EAR的根目录添加一个VersionCheckerV2.jar文件。在这个JAR文件中的VersionChecker类返回了Version 2.0。为了保证扩展类加载中的工具JAR可用,在EJB模块的manifest文件中添加一个引用,如例12-8:

  例12-8更新EJB模块的MANIFEST.MF文件

  Manifest-Version: 1.0

  Class-Path: VersionCheckerV2.jar

  现在的结果是:有一个Web模块,在它的WEB-INF/classes目录下面有一个servlet,在WEB-INF/lib目录下面有VersionCheckerV1.jar文件。还有一个EJB模块引用了EAR根目录下面的VersionCheckerV2.jar工具JAR。你期望Web模块装入VersionChecker类文件的版本是什么?是WEB-INF/lib下的Version 1.0还是工具JAR下面的Version 2.0?测试结果如例12-9:

  例12-9类加载例2

  VersionChecker called from Servlet

  VersionChecker is v2.0.

  Loaded bycom.ibm.ws.classloader.CompoundClassLoader@26282628

Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel

l\ClassloaderExample.ear\ClassloaderExampleEJB.jar;C:\WebSphere\AppServ

er\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\ClassloaderExample

.ear\VersionCheckerV2.jar

Delegation Mode: PARENT_FIRST

VersionChecker called from EJB

VersionChecker is v2.0.

Loaded bycom.ibm.ws.classloader.CompoundClassLoader@26282628

  Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel l\ClassloaderExample.ear\ClassloaderExampleEJB.jar;C:\WebSphere\AppServ

er\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\ClassloaderExample

.ear\VersionCheckerV2.jar

  Delegation Mode: PARENT_FIRST

  正如所看到的,当同时调用EJB模块和Web模块,VersionChecker是Version 2.0。当然,原因是:WAR类加载器将请求委托给了父类加载器而不是他自己,所以工具JAR就被同一个类加载器加载,而无需考虑请求是来自于servlet还是EJB。

  12.5.3步骤 3:改变WAR类加载的委托模式

  现在是否希望Web模块使用WEB-INF/lib目录下面的VersionCheckerV1.jar文件?为了这个目的,需要先将类加载委托模式从parent first改为parent last。
 
  设置委托模式为PARENT_LAST,使用如下步骤:

  1. 在向导栏选择Enterprise Applications;

  2. 选择ClassloaderExample应用程序;

  3. 在模块部分选择Manage modules ;

  4. 选择ClassloaderExampleWeb模块;

  5. 将类加载顺序修改成应用程序类加载优先(PARENT_LAST)。记住,这个条目应该称为WAR类加载优先,参见 “类加载/委托模式”;

  6. 单击OK.

  7. 保存配置;

  8. 重新启动应用程序。

  WEB-INF/lib下的VersionCheckerV1返回version of 1.0。可以在例12-10中看到:

  例12-10类加载例3

  VersionChecker called from Servlet

  VersionChecker is v1.0.

  Loaded bycom.ibm.ws.classloader.CompoundClassLoader@4d404d40

  Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel

l\ClassloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\classes;C:\W

  ebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\Cl

assloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\lib\VersionCheck

  erV1.jar;C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8

  Node02Cell\ClassloaderExample.ear\ClassloaderExampleWeb.war

  Delegation Mode: PARENT_LAST

  VersionChecker called from EJB

  VersionChecker is v2.0.

  Loaded bycom.ibm.ws.classloader.CompoundClassLoader@37f437f4

  Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel

  l\ClassloaderExample.ear\ClassloaderExampleEJB.jar;C:\WebSphere\AppServ

  er\profiles\AppSrv02\installedApps \kcgg1d8Node02Cell\ClassloaderExample

.ear\VersionCheckerV2.jar

  Delegation Mode: PARENT_FIRST

  如果你使用类加载器的搜索功能,搜索*VersionChecker*,会得到图12-9:

  图12-9类加载查看器搜索功能

  例12-11显示源代码

  例12-11类加载查看器搜索功能

  WAS Module Compound Class Loader (WAR class loader):

  file: / C: / WebSphere / AppServer / profiles / AppSrv02 /

  installedApps / kcgg1d8Node02Cell / ClassloaderExample.ear /

  ClassloaderExampleWeb.war / WEB-INF / lib / VersionCheckerV1.jar

  WAS Module Jar Class Loader (Application class loader):

  file: / C: / WebSphere / AppServer / profiles / AppSrv02 /

  installedApps / kcgg1d8Node02Cell / ClassloaderExample.ear /

  VersionCheckerV2.jar

  12.5.4步骤4:使用共享库共享工具JAR

  在此之前,只有一个应用程序使用VersionCheckerV2.jar文件。是否希望多个应用程序能够共享它?当然,你可以在每个EAR文件中把这个文件打包进去。但是如果需要修改这个工具JAR,那需要重新部署所有的应用程序。为了避免这个麻烦,你可以使用共享库全局共享这个JAR文件。

  共享库可以定义在单元、节点、应用程序服务器和集群。一旦你定义了共享库,必须将它跟应用程序服务器的类加载器或者单独的Web模块关联起来。根据共享库指派的目的地不同,WebSphere会使用匹配的类加载器加载共享库。

  只要愿意,可以定义多个共享库。也可以为应用程序、Web模块或者应用程序服务器指派多个共享库。

  在应用程序级别使用共享库

  定义一个名为VersionCheckerV2_SharedLib的共享库,并把它跟ClassloaderTest应用程序关联起来,步骤如下:

  1. 在管理控制台,选择Environment→Shared Libraries;

  2. 选择共享库的作用域,比如单元,单击New;

  3. 如图12-10:

  图12-10共享库配置

  –Name: 输入VersionCheckerV2_SharedLib;

  –Class path: 输入类路径中的条目,每个条目之间用回车隔开。如果提供绝对路径,建议是用WebSphere环境变量,比如%FRAMEWORK_JARS%/VersionCheckerV2.jar,确定你已经定义了一个和共享库相同作用域的变量。

  –Native library path: 输入JNI代码使用的DLLs和.so文件列表。

  4. 单击OK;

  5.选择Applications → Enterprise Applications;

  6. 选择应用程序ClassloadersExample ;

  7. 在引用选项,选择Shared library references ;

  8. 在应用程序列选择ClassloaderExample ;

  9. 单击Reference shared libraries;

  10. 选择VersionCheckerV2_SharedLib,单击>>按钮将选中的移动到Selected列,如下图12-11:

  图12-11指定一个共享库

  11.单击OK ;

  12.ClassloaderExample应用程序共享库配置窗口如下图12-12:

  图12-12将共享库指派给应用程序ClassloaderExample

  13.单击OK,保存配置。

  如果我们现在从EAR文件的根目录将VersionCheckerV2.jar删除,在EJB模块的manifest文件中也把引用删除,重新启动应用服务器,看到例12-12的结果。记住,Web模块的类加载顺序依然是应用程序类加载优先(PARENT_LAST)。

  例12-12类加载例4

  VersionChecker called from Servlet

  VersionChecker is v1.0.

  Loaded bycom.ibm.ws.classloader.CompoundClassLoader@2e602e60

  Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel

l\ClassloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\classes;C:\W

  ebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\Cl

  assloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\lib\VersionCheck

  erV1.jar;C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8
 
  Node02Cell\ClassloaderExample.ear\ClassloaderExampleWeb.war

  Delegation Mode: PARENT_LAST

  VersionChecker called from EJB

  VersionChecker is v2.0.

  Loaded bycom.ibm.ws.classloader.CompoundClassLoader@19141914

Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel

l\ClassloaderExample.ear\ClassloaderExampleEJB.jar;C:\henrik\VersionChe

ckerV2.jar

  Delegation Mode: PARENT_FIRST

  正如预料的,由于Web模块的委托模式,当servlet需要VersionChecker类,VersionCheckerV1.jar文件被加载。当EJB需要VersionChecker的类的时候,就会从指向C:\henrik\VersionCheckerV2.jar的共享库中加载它。如果你希望Web模块也使用共享库,只需要将类加载顺序恢复成缺省值,Web模块的类加载是父类加载优先。

  在应用程序服务器级别使用共享库

  共享库也可以跟应用程序服务器关联起来。在这个服务器上的部署的所有应用程序都能够看到共享库的代码列表。要把共享库跟应用程序服务器关联起来,首先要为应用程序服务器创建一个附加的类加载器,步骤如下:

  1. 选择应用程序服务器;

  2. 在应用程序基础结构部分,展开Java and Process Management,选择Class loader;

  3. 选择New,为这个类加载器选择类加载顺序,父类加载优先(PARENT_FIRST)或者应用程序类加载优先(PARENT_LAST),单击Apply;

  4. 单击刚刚创建的类加载器;

  5. 单击Shared library references;

  6. 单击Add,选择希望跟应用程序服务器关联的库。重复选择操作,将多个库跟这个类加载器关联。比如选择VersionCheckerV2_SharedLib条目;

  7. 单击OK;

  8. 保存配置;

  9. 重新启动应用程序服务器,修改才会生效。

  将VersionCheckerV2共享库跟应用程序服务器关联起来,就得到例12-13的结果。

  例12-13类加载例5

  VersionChecker called from Servlet

  VersionChecker is v1.0.

  Loaded bycom.ibm.ws.classloader.CompoundClassLoader@40c240c2

  Local ClassPath:

  C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cel

l\ClassloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\classes;C:\W

ebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\Cl

assloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\lib\VersionCheck

erV1.jar;C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8

Node02Cell\ClassloaderExample.ear\ClassloaderExampleWeb.war

VersionChecker called from EJB

VersionChecker is v2.0.

  Loaded bycom.ibm.ws.classloader.ExtJarClassLoader@7dee7dee

  Local ClassPath: C:\henrik\VersionCheckerV2.jar

  Delegation Mode: PARENT_FIRST

  我们定义的新的名为ExtJarClassLoader类加载器,在EJB模块请求时,它装入VersionCheckerV2.jar文件。由于委托模式,WAR类加载器继续装入自己的version。

  12.6类加载器问题诊断

  JVM 5.0提供了一些配置,可以让我们查看详细的类装入,比如JVM参数 -verbose:dynload、-Dibm.cl.verbose=<name>。

  在实际开发过程中,如果使用不当,会出现很多类加载相关的问题。当遇到类加载问题时,可以查看WAS的相关日志,在日志中出现如下异常,可以认为是类加载器出现了问题:

  ClassCastException

  ClassNotFoundException

  NoClassDefFoundError

  NoSuchMethodError

  IllegalArgumentException

  UnsatisfiedLinkError

  VerifyError

  关于问题诊断,将在下一篇文章《WAS 6.1类加载问题诊断》详细阐述。

  总结

  本文针对WAS6.1版本,详细介绍了类加载的概念以及如何客户化,并通过几个例子向大家讲述了影响类加载的选项的使用。虽然WAS 6.1允许根据需要修改类加载策略,比如将父类优先改成应用程序优先,但是不推荐这么使用。笔者曾经就遇到因为修改策略,导致应用程序无法启动。原因是WAS中 的组件和应用程序使用的某些类是一致的,加载策略选择不正确,就会导致类加载错误。

posted @ 2014-03-04 11:10 Eric_jiang 阅读(1547) | 评论 (0)编辑 收藏

<%@ page import="java.security.Provider"%>
<%@ page import="java.security.Security"%>
<%@ page import="java.util.Set"%>
<%@ page import="java.util.Iterator"%>
<%
Provider[] providers = Security.getProviders();
for (int i = 0; i < providers.length; i++) {
Provider provider = providers[i];
%> 
  Provider name:  <%=provider.getName()%><br/>
  Provider information:  <%=provider.getInfo()%> <br/>
  Provider version:  <%=provider.getVersion()%><br/>
<%
Set entries = provider.entrySet();
Iterator iterator = entries.iterator();
while (iterator.hasNext()) {
%>
Property entry:<%=iterator.next()%><br/><br/><br/>
<%
}
}
%> 
 
posted @ 2014-02-27 14:26 Eric_jiang 阅读(243) | 评论 (0)编辑 收藏

OA应用程序的性能测试包括了benchmarking test(基准测试),capacity test(容量测试)和soak test(浸泡测试)三个主要测试阶段。  

基准测试(Benchmarking Test)

基于SOA的性能测试第一阶段是基准测试,基准测试是用来确定被测应用程序是否存在性能衰退,并且收集可重复性能测试结果以作为性能基准。基准测试的最好方法是每次测试只改变一个参数。基准测试包括了相应时间驱动的测试和吞吐量驱动的测试。

响应时间驱动测试

对于web service的应用程序,其中响应时间定义为发送一个服务请求到收到服务响应的时间间隔。响应时间驱动的测试主要用来测试单个service的性能。首先加一个虚拟用户作为负载量,然后对同一测试用例按照比例的增加并发虚拟用户数,并分别记录下测试结果,最后计算出这些测试结果的平均值作为平均响应时间。

下图为某个web服务在不同并发虚拟用户数下平均响应时间曲线图,由图可看出,平均响应时间随着并发虚拟用户数的增加而增加。在用户数从50到100,平均响应时间开始比较大幅度地增长,此时很有可能某个系统资源出现了瓶颈,当然前提条件是在被测应用程序没有出现错误的情况下。此时可以进行调优,但要保证每次只改动一个参数值,然后再次执行相同测试用例,并与之前的结果进行对比,选取结果最优的参数配置。(图略)

吞吐量驱动测试

吞吐量被定义为在单元时间内能够成功处理的服务请求的数量。吞吐量驱动的测试主要是基于一组连续web服务形成一个或多个测试场景,来测量应用在单位时间内能够处理的事务数量。

这是针对一个业务场景进行的性能测试用例,同样首先加一个虚拟用户作为负载量,然后对同一测试用例按比例的增加并发虚拟用户数,最后记录下不同虚拟用户数下的吞吐量。

下图为不同并发虚拟用户数下吞吐量的曲线图,与响应时间一样,吞吐量也随着并发虚拟用户数的增长而增长,但不同的是吞吐量在达到某一最高点后,再增加并发虚拟用户时吞吐量则保持与最高值接近。这是由于当用户数较少时,单位时间内发出的服务请求较少,所以测出的吞吐量较小,当用户数增加,发出的服务请求增加,所以吞吐量也随之增加,当吞吐量达到最高值表明被测应用在测试的硬件环境下达到处理事务的最高能力。最后同样要做性能调优,以选取最优的吞吐量最大值时的配置情况。(图略)

容量测试(Capacity Test)

容量测试的目标是要看被测应用在一定测试环境下能够达到的最大处理能力。容量测试将模拟更加接近真实用户使用的环境,并且用更为真实的用户负载来测试 SOA应用程序的capacity scale。具体地说,一般容量测试是为了检测在达到一定响应时间或吞吐量的前提下被测应用能够支持的并发用户数。其中容量测试包括了以下几方面内容:
  • 定义访问系统的并发虚拟用户数
  • 定义虚拟用户的think time,也就是发出两个连续请求之间的时间间隔。
  • 用ramp-up run的方式增加负载量进行测试,得到被测应用能够支持的虚拟用户数的范围。
  • 在应用支持的用户数地范围内,采用flat run的方式进行测试,以得到更为精确性能结果。

浸泡测试(Soak Test)

Soak test是在一个稳定的并发用户上进行的long run测试,用来测试SOA应用程序的健壮性。通过soak test往往可以发现内存泄露,频繁 GC 等严重性能问题。进行soak test需要注意以下两点:
  • Soak test需要在一定适中的用户负载量下进行,最好低于应用支持最大的负载量。
  • 在执行long run测试时,采用几种不同用户组,并且每个用户组织性不同的业务流程。

Soak test实际上比较简单的性能测试,测试最好能够运行几天,以真正得到一个健壮的应用。确保应用测试是贴近真实世界,尽量与实际使用情况接近。
posted @ 2014-02-26 11:06 Eric_jiang 阅读(289) | 评论 (0)编辑 收藏

ed2k://|file|00.引论篇.单片机技术概论--力天手把手教你学单片机之引论篇(ED2000.COM).rar|116198953|04993919cda266c7ae254d9e1f16a754|h=r4yybdb755ei5y6wwr3deuokjv32sz2o|/
ed2k://|file|测板视频(ED2000.COM).rar|87174303|738bb1def1745290005db57f0b45be17|h=rwj2egwwlkfzmz3h54jh6ija3pkuvoim|/
ed2k://|file|F1.附录一.LT-Super51开发板测板视频--力天手把手教你学单片机之附录篇(ED2000.COM).rar|87252539|e7bed47466fd582d9f712516fe5c780f|h=2nolsdwfhqgmc3ihfn7s5rcss32oz2bz|/
ed2k://|file|F2.附录二.Keil软件与仿真芯片简介--力天手把手教你学单片机之附录篇(ED2000.COM).rar|40071996|54570a6a528a95a3c59973257abb4482|h=3bjcz2jgakgnrt4xzf5cxw4h6ukuuu7o|/
ed2k://|file|01.第一讲.个人电脑使用入门上--力天手把手教你学单片机之入门篇(ED2000.COM).rar|70706563|1dd4a35ee3c8cc9096c8dd68cc38bfaf|h=meh5uqabezlzrp72c2tvccj3wxkmk3su|/
ed2k://|file|02.第一讲.个人电脑使用入门下--力天手把手教你学单片机之入门篇(ED2000.COM).rar|44356449|4e6b68176a38bdcb8b8e789e4c0928c7|h=ykdppuumqfqaienrwdefofi6lrbsrrfl|/
ed2k://|file|03.第二讲.硬件技术基本知识上--力天手把手教你学单片机之入门篇(ED2000.COM).rar|92332119|81290b5c6055fca5485e32309c3acf8e|h=qqq4uzd6ir2thkia47rnscrzob36ppmf|/
ed2k://|file|04.第二讲.硬件技术基础知识下--力天手把手教你学单片机之入门篇(ED2000.COM).rar|106525273|040e88a053ef869c38491c0872a8f464|h=hshxdsyg2raofwf36qtffh6kadrf7qzl|/
ed2k://|file|05.第三讲.数字电路基础知识上--力天手把手教你学单片机之入门篇(ED2000.COM).rar|87904764|22e07a3ff94a4a93b9eeaa55cd79b6d4|h=pf3yntcv7xteagoenrwwsdi3tps7cz5q|/
ed2k://|file|06.第三讲.数字电路基础知识下--力天手把手教你学单片机之入门篇(ED2000.COM).rar|190036276|3eda75d4beda8f7c818858077d4b7391|h=fwbupymnho2yttdmswxny7pmngnngqvn|/
ed2k://|file|07.第四讲.C语言基础知识--力天手把手教你学单片机之入门篇(ED2000.COM).rar|56984538|a1e21c8b5f08a878d07dec4bffce0913|h=dtl2mkwexowopvegullkzvzzlwsri5vu|/
ed2k://|file|08.第五讲.51单片机最小系统上--力天手把手教你学单片机之基础篇(ED2000.COM).rar|113912150|494f52ec21225b7a5f5484dad67a36a5|h=buxo3bdu6rh6ivjli4ujxu272y4fdvdw|/
ed2k://|file|09.第五讲.51单片机最小系统下--力天手把手教你学单片机之基础篇(ED2000.COM).rar|71018952|5495edfcafaec2cc811d78084b58e70c|h=tecyreeeeyrr2gj2i4mnu7tgkr7iquq7|/
ed2k://|file|10.第六讲.C语言数据类型及表达式上--力天手把手教你学单片机之基础篇(ED2000.COM).rar|78411079|1affbd3650cb88686f8b7ccfd9ff3f48|h=sc526w36iirl54vixluliyi4bg2oizas|/
ed2k://|file|11.第六讲.C语言数据类型及表达式下--力天手把手教你学单片机之基础篇(ED2000.COM).rar|74736608|586c2f433542f51e8da7e2fe3a62c435|h=vhtzevx4guf7tqlc2t7cr2ua5jc4corq|/
ed2k://|file|12.第七讲.C语言的三种语句结构上--力天手把手教你学单片机之基础篇(ED2000.COM).rar|92409556|58a2fbbdbbe5e3ec7b70e03ab65613a3|h=5jfvo7w7me6tppcw4rioelkfkax3lndr|/
ed2k://|file|13.第七讲.C语言的三种语句结构中--力天手把手教你学单片机之基础篇(ED2000.COM).rar|81186040|8a8530338be5ff1c9c3cce9129f2d2f2|h=tpcxswdr4735f6vfjgkwc6peaep5dxi7|/
ed2k://|file|14.第七讲.C语言的三种语句结构下--力天手把手教你学单片机之基础篇(ED2000.COM).rar|119030765|2cc7fbb81468cbd11413579a33517d8a|h=zxtp2o373qlmf5jxfaplcwgmr56qwwsm|/
ed2k://|file|15.第八讲.C语言函数与预处理上--力天手把手教你学单片机之基础篇(ED2000.COM).rar|104871043|ec7ad639bde6a516a01a8f76c0d79a86|h=koukgq2tghashva4czql5zzlvhklmrbj|/
ed2k://|file|16.第八讲.C语言函数与预处理下--力天手把手教你学单片机之基础篇(ED2000.COM).rar|136901486|104df53529b0cb00e9460f3929b01022|h=wzluqrqpi2iui45otg64yns32qs2tg6j|/
ed2k://|file|17.第九讲.输出型外设与51的IO口上--力天手把手教你学单片机之实战篇(ED2000.COM).rar|73325409|7cdb241632cbb32daf51b471d79f9eaf|h=64ds2lrbkwrb7q4m2brjqdtwifxecod7|/
ed2k://|file|18.第九讲.输出型外设与51的IO口中--力天手把手教你学单片机之实战篇(ED2000.COM).rar|94226255|b41df92c7064221dd6cb7361b3b429e4|h=f6ifvjekxuqnlmqjolrcjkmukahuwxoq|/
ed2k://|file|19.第九讲.输出型外设与51的IO口下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|153946670|f2263f26eb08e22c8f4920959e03d843|h=lp4nzrzbqhg5til5pxwcmllnjznwc5xk|/
ed2k://|file|20.第十讲.单个按键与中断上--力天手把手教你学单片机之实战篇(ED2000.COM).rar|93598612|c2d50f545db19cb50d243fd38b5d38e0|h=wvq7smbwnlrupukyoey7gybjsdoyqoze|/
ed2k://|file|21.第十讲.单个按键与中断中--力天手把手教你学单片机之实战篇(ED2000.COM).rar|105926905|f945adc2290b709463c893a4c712be03|h=y44dshsprqon254hsgfowdgpmi6q7y3t|/
ed2k://|file|22.第十讲.单个按键与中断下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|77841692|7b119a68fb5b2af645ebfefb5afa0d0c|h=swgiwxsdral7mtltcmscrkjivi5j3fn5|/
ed2k://|file|23.第十一讲.数码管与定时器上--力天手把手教你学单片机之实战篇(ED2000.COM).rar|84099347|c9e222594efe1a82943d2f231a0f46c5|h=hdexi5znisj734bszgwevtbsodh72cvz|/
ed2k://|file|24.第十一讲.数码管与定时器中--力天手把手教你学单片机之实战篇(ED2000.COM).rar|143310474|6496593f40d8efb741a3cbe9b6493967|h=a2p7aftixioythhydp6bn63o3q43ofwn|/
ed2k://|file|25.第十一讲.数码管与定时器中下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|127917403|e54d013831d33f09d89b8c9633f36d58|h=oej6awqbb7nbbsnnc6z3xedfyn3qbqau|/
ed2k://|file|26.第十一讲.数码管与定时器下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|134759743|295368255a81b50315202678bc36f835|h=h4uk5fm7cpvkxgbhpxsk2cqt4p7fohv2|/
ed2k://|file|27.第十二讲.矩阵键盘上--力天手把手教你学单片机之实战篇(ED2000.COM).rar|96733666|6b498a4d08597e2d450e207557d613fb|h=xq74tbqfaiyhmd3hp63dru7qw2wj2fdp|/
ed2k://|file|28.第十二讲.矩阵键盘下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|82126983|3bf9553923cacf46ff73be2a20c5cfcf|h=o43ldxl5apxdbp4mey25scdszhhualid|/
ed2k://|file|29.第十二讲.专题一之头文件与模块化编程详解上--力天手把手教你学单片机之附录篇(ED2000.COM).rar|81946415|05f7c9d194496418bf106df0ebd7de3c|h=lpypjbkrtufogkcniz22ti7f75zeinsm|/
ed2k://|file|30.第十二讲.专题一之头文件与模块化编程详解中--力天手把手教你学单片机之附录篇(ED2000.COM).rar|100729778|feba3a57adb8006f49aa8ffc9784fad7|h=q2dehsegzka5i34qe3lkivdsy5viiv5a|/
ed2k://|file|31.第十二讲.专题一之头文件与模块化编程详解下--力天手把手教你学单片机之附录篇(ED2000.COM).rar|88298330|242d113db23dde67795bf2d9b1b5af58|h=iofeh5ssgzuwh54bonxkxfg5vs252nkb|/
ed2k://|file|32.第十三讲.异步串行通信上--力天手把手教你学单片机之实战篇(ED2000.COM).rar|77877845|e0e9f2b7a33371da85cced8550fc684f|h=fpgfqm2ityfkjncml3bqxwt4v2moco6k|/
ed2k://|file|33.第十三讲.异步串行通信中--力天手把手教你学单片机之实战篇(ED2000.COM).rar|87492573|b319aa1a4bf677bd018fe2736fe8d04b|h=yvzadbri3isxooedfgsw4xlmd67n5rrn|/
ed2k://|file|34.第十三讲.异步串行通信中下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|141727825|149484e738c7eb3de861bfe41a8c2098|h=uk3ennvddpbqo5hygdwu5bhmkksyolsl|/
ed2k://|file|35.第十三讲.异步串行通信下--力天手把手教你学单片机之实战篇(ED2000.COM).rar|79633620|3f0fc643164c78544f0dd19a00f3af15|h=qni3nckecwkzx66r3th3l33yr2j2sikt|/
ed2k://|file|36.第十四讲.SPI接口与DS1302一--力天手把手教你学单片机之实战篇(ED2000.COM).rar|84404944|0d90567cc5bc52df5dc637dd2bcf3ca9|h=pj4yerjbqwqcavqgsoxp4llvaa2j6hg2|/
ed2k://|file|37.第十四讲.SPI接口与DS1302二--力天手把手教你学单片机之实战篇(ED2000.COM).rar|85216414|402f81e6bdeb40e226dca416ebaf16eb|h=uohl7lgb5td2kimincmzqdnvcztipiq5|/
ed2k://|file|38.第十四讲.SPI接口与DS1302三--力天手把手教你学单片机之实战篇(ED2000.COM).rar|161674644|71deb074c4cd3469fae7ce5d0b725b94|h=gfi4h6dmqaanq6s4s6ozlw6eq3p5szjy|/
ed2k://|file|39.第十四讲.SPI接口与DS1302四--力天手把手教你学单片机之实战篇(ED2000.COM).rar|100130738|0efe0a45f00aad48f47eca8d88bce3ec|h=uiq43qi7efdxcbluldqogsb2rq77ih7h|/
ed2k://|file|40.第十四讲.SPI接口与DS1302五--力天手把手教你学单片机之实战篇(ED2000.COM).rar|95816321|42a72c632250c01a010fda0314db4a0c|h=ywklgocdsosutegm6esr5bnpmzhmy3nn|/
ed2k://|file|01用户手册【力天电子原创www.LT430.com】(ED2000.COM).rar|1367735|6fbe3deb36554dc50f35af23fae88226|h=7p6pv3y53su5nqbvw2wbsxopcev7nnby|/
ed2k://|file|02电路图【力天电子原创www.LT430.com】(ED2000.COM).rar|5632719|5f72617b2cbc431a3b4e6c0eb94bcf6e|h=ouyekd6ycyayod3oo4uplcbwjzl4b4qo|/
ed2k://|file|03例程代码【力天电子原创www.LT430.com】(ED2000.COM).rar|30874083|93933fe948eb439b228617dfa19faa1f|h=babtbvjd2dvypypnp5b2grzvt56qfgvo|/
ed2k://|file|04数据手册【力天电子原创www.LT430.com】(ED2000.COM).rar|15053425|30fa2af2a85c0efa121d2b6e03dd1da5|h=xevvrivdk24qjw5cua7x23hnkthh3iph|/
ed2k://|file|05开发软件【力天电子原创www.LT430.com】(ED2000.COM).rar|37069108|7d1efc6cc416c473c747aa116f4f67b1|h=qcptsagqatkjqpnz3wwpe77ljmdxblaq|/
ed2k://|file|03例程代码(ED2000.COM).rar|30765342|2afdab30d4209e97168a405956f32e91|h=lzi345qpgvchgkzroliuacvcsc4lwxge|/
ed2k://|file|41.第十五讲.SPI接口与DS1302六--力天手把手教你学单片机之实战篇七(ED2000.COM).rar|90014503|5534fe398aa5f4d1854fa0881415b11c|h=lizwjgbuq5urc2wx4jjhdzio3tjwnirg|/
ed2k://|file|42.第十五讲.SPI接口与DS1302七--力天手把手教你学单片机之实战篇七(ED2000.COM).rar|119435391|09de8cb0ed0b8617e42d2e7480dfa978|h=c53t2inh67vcldlnje5uiccufsqcfwuz|/
ed2k://|file|43.第十六讲.IIC接口与AT24C02一--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|88564982|4914cb676bc9d411895cd0d3bcda42fb|h=kf2e4too2dj2naxnhuihp2t7qgcwa3xp|/
ed2k://|file|44.第十六讲.IIC接口与AT24C02二--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|101793624|39e882425a20f91fdf600effcf7978d9|h=ezi6x5mvtaykkoo4czi6ix56dajyffqc|/
ed2k://|file|45.第十六讲.IIC接口与AT24C02三--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|73099158|7017886c3e8f296bb36ac700144babfe|h=oki5m7ehjxhbcixvvuqkqtb3t4e7q4ox|/
ed2k://|file|46.第十六讲.IIC接口与AT24C02四--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|98541388|75c686b408f1b301962dc458f7dd473f|h=s2ny5m3ailghiclv2nipjf6e3jvwus6t|/
ed2k://|file|47.第十六讲.IIC接口与AT24C02五--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|64191448|c7e458150320cc0f2aa0c8d17e1e0bad|h=bgkcjw5fadacmriwg5p25kiehenee62c|/
ed2k://|file|48.第十六讲.IIC接口与AT24C02六--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|84001540|3ee9e8b78970eb3e4607bc84b36d9e0f|h=omo4ps3phrht4hahp76lc4s2ksm47kwr|/
ed2k://|file|49.第十六讲.IIC接口与AT24C02七--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|87094227|dae23f6af62860c859322cb3ca71c261|h=b64ogps7o3dut3o6727pafu3dznwkmff|/
ed2k://|file|50.第十六讲.IIC接口与AT24C02八--力天手把手教你学单片机之实战篇八(ED2000.COM).rar|38441693|2cd216ed57e839e8ae64b7839befa3a8|h=vvbeuv2ml2gyzlyorigxzbun2p7geupi|/
ed2k://|file|51.第十七讲.专题二:串行通讯与并行通讯一--力天手把手教你学单片机之实战篇九(ED2000.COM).rar|76844269|56257589b93f82cefd1f5d8892514bc8|h=bqp3dxketimariaek5lyp7mozzhelbju|/
ed2k://|file|52.第十七讲.专题二:串行通讯与并行通讯二--力天手把手教你学单片机之实战篇九(ED2000.COM).rar|121677398|9038a9c8b59f8f5e2105a941a6583235|h=gua2cdy7h36zghxh72ye7e3z4vdvzdhw|/
ed2k://|file|53.第十八讲.模数转换器ADC0804一--力天手把手教你学单片机之实战篇十(ED2000.COM).rar|94360616|219bfe8e3ae18bb61c95c051b1e3950d|h=pxhuj3ga4sxrnnvkcryta32mjxpwusy7|/
ed2k://|file|54.第十八讲.模数转换器ADC0804二--力天手把手教你学单片机之实战篇十(ED2000.COM).rar|88779494|7a8bdc6c88e0c98d019ef40374a1ac12|h=t7bvwua6bvs5qw5l2iy3stdbou6nfbqx|/
ed2k://|file|55.第十八讲.模数转换器ADC0804三--力天手把手教你学单片机之实战篇十(ED2000.COM).rar|65213047|3e47deaea1db10c234cd621d4ed08bc8|h=qehsshsi6l45wrdfixcakxqlefc6cavf|/
ed2k://|file|56.第十八讲.模数转换器ADC0804四--力天手把手教你学单片机之实战篇十(ED2000.COM).rar|86427611|a0177f7c349ebab87c8a021f2ae06707|h=dw3mlu6sgfglbp6r6633iuot6rojl7rt|/
ed2k://|file|57.第十八讲.模数转换器ADC0804五--力天手把手教你学单片机之实战篇十(ED2000.COM).rar|106459634|b5221adfc8f6e5a1d4975ff6752e69e4|h=5xf76yhei2gtuil2zo77kvbhcuybtdog|/
ed2k://|file|58.第十八讲.数模转换器DAC0832一--力天手把手教你学单片机之实战篇十一(ED2000.COM).rar|67479391|2779bc7f91027602141dc11d1c207b1a|h=idbd4zxnjzgkf3b7jh4mq5b7neyfgi2p|/
ed2k://|file|59.第十八讲.数模转换器DAC0832二--力天手把手教你学单片机之实战篇十一(ED2000.COM).rar|114120160|296b30db780d3b5b82d557b511b6e2bf|h=d7bygbkdydawnt2aohto3taopnvbtwi7|/
ed2k://|file|60.第十八讲.数模转换器DAC0832三--力天手把手教你学单片机之实战篇十一(ED2000.COM).rar|71594266|b8e810699e6343ba51b3184f96804673|h=eia5syqio34iqzjqy3e3gybkm36qcsaw|/
ed2k://|file|61.第十八讲.数模转换器DAC0832四--力天手把手教你学单片机之实战篇十一(ED2000.COM).rar|71140207|243e813469cf1f510e8b57e6ca304389|h=zintu4pjsk5iwgiwpgahb37x5d6xqe2c|/
posted @ 2014-01-24 10:13 Eric_jiang 阅读(468) | 评论 (0)编辑 收藏

在linux中启动crontab服务:

/etc/init.d/crond  start

crontab的命令格式

crontab -l   显示当前的crontab 文件(默认编写的crontab文件会保存在 (/var/spool/cron/用户名   例如: /var/spool/cron/roger)

crontab -r 删除当前的crontab (谨慎使用此方法,因为将会把所有的计划任务全部删除)

 

crontab -e 使用编辑器编辑当前的crontab文件

 

crontab 的文件格式:

 

                 minutes          hour            day-of-month           month-of-year       day-of-week            commands

例如:

                    0                 4                     *                               *                           2,5                 /usr/bin/wall</etc/motd

*************解释:每周的周二和周五广播  /etc/motd中的信息************************************************

                   */2             12-14               *                             3-6,9-12                   1-5                   bash_scripts

*******************解释:每年的3-6月份,以及9-12月份的周一到周五的下午12-14点,每隔两分钟执行一个脚本*****

 

crontab的配置文件放在 /etc/crontab中


第1列分钟1~59
第2列小时1~23(0表示子夜)
第3列日1~31
第4列月1~12
第5列星期0~6(0表示星期天)
第6列要运行的命令

下面是crontab的格式:
分 时 日 月 星期 要运行的命令

这里有crontab文件条目的一些例子:

30 21 * * * /usr/local/apache/bin/apachectl restart
上面的例子表示每晚的21:30重启apache。

45 4 1,10,22 * * /usr/local/apache/bin/apachectl restart
上面的例子表示每月1、10、22日的4 : 45重启apache。

10 1 * * 6,0 /usr/local/apache/bin/apachectl restart
上面的例子表示每周六、周日的1 : 10重启apache。

0,30 18-23 * * * /usr/local/apache/bin/apachectl restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。

0 23 * * 6 /usr/local/apache/bin/apachectl restart
上面的例子表示每星期六的11 : 00 pm重启apache。

* */1 * * * /usr/local/apache/bin/apachectl restart
每一小时重启apache

* 23-7/1 * * * /usr/local/apache/bin/apachectl restart
晚上11点到早上7点之间,每隔一小时重启apache

0 11 4 * mon-wed /usr/local/apache/bin/apachectl restart
每月的4号与每周一到周三的11点重启apache

0 4 1 jan * /usr/local/apache/bin/apachectl restart
一月一号的4点重启apache



posted @ 2014-01-22 16:54 Eric_jiang 阅读(221) | 评论 (0)编辑 收藏

Gdb 调试器
调试是所有程序员都会面临的问题。如何提高程序员的调试效率,更好更快地定位程序中的问题从而加快程序开发的进度,是大家共同面对的。就如读者熟知的Windows下的一些调试工具,如VC自带的如设置断点、单步跟踪等,都受到了广大用户的赞赏。那么,在Linux下有什么很好的调试工具呢?
本文所介绍的Gdb 调试器是一款GNU 开发组织并发布的UNIX/Linux 下的程序调试工具。虽然,它没有图形化的友好界面,但是它强大的功能也足以与微软的VC 工具等媲美。
下面就请跟随笔者一步步学习Gdb调试器。
3.5.1 Gdb使用流程
这里给出了一个短小的程序,由此带领读者熟悉一下Gdb 的使用流程。建议读者能够实
际动手操作。
首先,打开Linux 下的编辑器Vi或者Emacs,编辑如下代码(由于为了更好地熟悉Gdb的操作,笔者在此使用Vi 编辑,希望读者能够参见3.3 节中对Vi 的介绍,并熟练使用Vi)。
/*test.c*/
#include <stdio.h>
int sum(int m);
int main()
{
int i,n=0;
sum(50);
for(i=1; i<=50; i++)
{
n += i;
}
printf("The sum of 1-50 is %d \n", n );
}
int sum(int m)
{
int i,n=0;
for(i=1; i<=m;i++)
n += i;
printf("The sum of 1-m is %d\n", n);
}
在保存退出后首先使用Gcc对test.c进行编译,注意一定要加上选项“-g”,这样编译出的可执行代码中才包含调试信息,否则之后Gdb 无法载入该可执行文件。
[root@localhost Gdb]# gcc -g test.c -o test
虽然这段程序没有错误,但调试完全正确的程序可以更加了解Gdb 的使用流程。接下来就启动Gdb 进行调试。注意,Gdb 进行调试的是可执行文件,而不是如“.c”的源代码,因此,需要先通过Gcc编译生成可执行文件才能用Gdb进行调试。
[root@localhost Gdb]# gdb test
GNU Gdb Red Hat Linux (6.3.0.0-1.21rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db
library "/lib/libthread_db.so.1".
(gdb)
可以看出,在Gdb 的启动画面中指出了Gdb 的版本号、使用的库文件等信息,接下来就进入了由“(gdb)”开头的命令行界面了。
(1)查看文件
在 Gdb 中键入“l”(list)就可以查看所载入的文件,如下所示:
注意
在Gdb的命令中都可使用缩略形式的命令,如“l”代便“list”,“b”代表“breakpoint”,“p”代表“print”等,读者也可使用“help”命令查看帮助信息。
(Gdb) l
1 #include <stdio.h>
2 int sum(int m);
3 int main()
4 {
5 int i,n=0;
6 sum(50);
7 for(i=1; i<=50; i++)
8 {
9 n += i;
10 }
(Gdb) l
11 printf("The sum of 1~50 is %d \n", n );
12
13 }
14 int sum(int m)
15 {
16 int i,n=0;
17 for(i=1; i<=m;i++)
18 n += i;
19 printf("The sum of 1~m is = %d\n", n);
20 }
可以看出,Gdb 列出的源代码中明确地给出了对应的行号,这样就可以大大地方便代码的定位。
(2)设置断点
设置断点是调试程序中是一个非常重要的手段,它可以使程序到一定位置暂停它的运行。因此,程序员在该位置处可以方便地查看变量的值、堆栈情况等,从而找出代码的症结所在。
在 Gdb 中设置断点非常简单,只需在“b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点)。如下所示:
(Gdb) b 6
Breakpoint 1 at 0x804846d: file test.c, line 6.
要注意的是,在Gdb 中利用行号设置断点是指代码运行到对应行之前将其停止,如上例中,代码运行到第5行之前暂停(并没有运行第5行)。
(3)查看断点情况
在设置完断点之后,用户可以键入“info b”来查看设置断点情况,在Gdb 中可以设置
多个断点。
(Gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0804846d in main at test.c:6
(4)运行代码
接下来就可运行代码了,Gdb默认从首行开始运行代码,可键入“r”(run)即可(若想从程序中指定行开始运行,可在r 后面加上行号)。
(Gdb) r
Starting program: /root/workplace/Gdb/test
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x5fb000
Breakpoint 1, main () at test.c:6
6 sum(50);
可以看到,程序运行到断点处就停止了。
(5)查看变量值
在程序停止运行之后,程序员所要做的工作是查看断点处的相关变量值。在Gdb 中只需
键入“p”+变量值即可,如下所示:
(Gdb) p n
$1 = 0
(Gdb) p i
$2 = 134518440
在此处,为什么变量“i”的值为如此奇怪的一个数字呢?原因就在于程序是在断点设置的对应行之前停止的,那么在此时,并没有把“i”的数值赋为零,而只是一个随机的数字。但变量“n”是在第四行赋值的,故在此时已经为零。
小技巧
Gdb 在显示变量值时都会在对应值之前加上“$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作“$N”,而无需写冗长的变量名。
(6)单步运行
单步运行可以使用命令“n”(next)或“s”(step),它们之间的区别在于:若有函数调用的时候,“s”会进入该函数而“n”不会进入该函数。因此,“s”就类似于VC等工具中的
“step in”,“n”类似与VC等工具中的“step over”。它们的使用如下所示:
(Gdb) n
The sum of 1-m is 1275
7 for(i=1; i<=50; i++)
(Gdb) s
sum (m=50) at test.c:16
16 int i,n=0;
可见,使用“n”后,程序显示函数sum的运行结果并向下执行,而使用“s”后则进入到sum函数之中单步运行。
(7)恢复程序运行
在查看完所需变量及堆栈情况后,就可以使用命令“c”(continue)恢复程序的正常运行了。这时,它会把剩余还未执行的程序执行完,并显示剩余程序中的执行结果。以下是之前使用“n”命令恢复后的执行结果:
(Gdb) c
Continuing.
The sum of 1-50 is :1275
Program exited with code 031.
可以看出,程序在运行完后退出,之后程序处于“停止状态”。
小知识
在Gdb中,程序的运行状态有“运行”、“暂停”和“停止”3种,其中“暂停”状态为程序遇到了断点或观察点之类的,程序暂时停止运行,而此时函数的地址、函数参数、函数内的局部变量都会被压入“栈”(Stack)中。故在这种状态下可以查看函数的变量值等各种属性。但在函数处于“停止”状态之后,“栈”就会自动撤销,它也就无法查看各种信息了。
3.5.2 Gdb基本命令
Gdb 的命令可以通过查看help 进行查找,由于Gdb 的命令很多,因此Gdb 的help 将其分成了很多种类(class),用户可以通过进一步查看相关class找到相应命令。如下所示:
(gdb) help
List of classes of commands:
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreViations are allowed if unambiguous.
上述列出了Gdb 各个分类的命令,注意底部的加粗部分说明其为分类命令。接下来可以
具体查找各分类种的命令。如下所示:
(gdb) help data
Examining data.
List of commands:
call -- Call a function in the program
delete display -- Cancel some expressions to be displayed when program stops
delete mem -- Delete memory region
disable display -- Disable some expressions to be displayed when program stops
Type "help" followed by command name for full documentation.
Command name abbreViations are allowed if unambiguous.
至此,若用户想要查找call命令,就可键入“help call”。
(gdb) help call
Call a function in the program.
The argument is the function name and arguments, in the notation of the
current working language. The result is printed and saved in the value
history, if it is not void.
当然,若用户已知命令名,直接键入“help [command]”也是可以的。
Gdb 中的命令主要分为以下几类:工作环境相关命令、设置断点与恢复命令、源代码查看命令、查看运行数据相关命令及修改运行参数命令。以下就分别对这几类的命令进行讲解。
1.工作环境相关命令
Gdb中不仅可以调试所运行的程序,而且还可以对程序相关的工作环境进行相应的设定,甚至还可以使用shell 中的命令进行相关的操作,其功能极其强大。表3.10 所示为Gdb 常见工作环境相关命令。
表3.10 Gdb 工作环境相关命令
命令格式 含义
set args 运行时的参数指定运行时参数,如set args 2
show args 查看设置好的运行参数
path dir 设定程序的运行路径
show paths 查看程序的运行路径
set enVironment var [=value] 设置环境变量
show enVironment [var] 查看环境变量
cd dir 进入到dir目录,相当于shell中的cd命令
pwd 显示当前工作目录
shell command 运行shell的command命令
2.设置断点与恢复命令
Gdb 中设置断点与恢复的常见命令如表3.11 所示。
表 3.11 Gdb 设置断点与恢复相关命令
命令格式  含义
bnfo b 查看所设断点
break 行号或函数名 <条件表达式> 设置断点
tbreak 行号或函数名 <条件表达式> 设置临时断点,到达后被自动删除
delete [断点号] 删除指定断点,其断点号为“info b”中的第一栏。若缺省断点号则删除所有断点
disable [断点号]] 停止指定断点,使用“info b”仍能查看此断点。同delete一样,省断点号则停止所有断点
enable  [断点号] 激活指定断点,即激活被disable停止的断点
condition [断点号] <条件表达式> 修改对应断点的条件
ignore [断点号]<num> 在程序执行中,忽略对应断点num次
step 单步恢复程序运行,且进入函数调用
next 单步恢复程序运行,但不进入函数调用
finish 运行程序,直到当前函数完成返回
c 继续执行函数,直到函数结束或遇到新的断点
由于设置断点在Gdb 的调试中非常重要,所以在此再着重讲解一下Gdb中设置断点的方法。Gdb 中设置断点有多种方式:其一是按行设置断点,设置方法在3.5.1节已经指出,在此就不重复了。另外还可以设置函数断点和条件断点,在此结合上一小节的代码,具体介绍后两种设置断点的方法。
① 函数断点
Gdb 中按函数设置断点只需把函数名列在命令“b”之后,如下所示:
(gdb) b sum
Breakpoint 1 at 0x80484ba: file test.c, line 16.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080484ba in sum at test.c:16
要注意的是,此时的断点实际是在函数的定义处,也就是在16 行处(注意第16 行还未
执行)。
② 条件断点
Gdb 中设置条件断点的格式为:b 行数或函数名if 表达式。具体实例如下所示:
(gdb) b 8 if i==10
Breakpoint 1 at 0x804848c: file test.c, line 8.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0804848c in main at test.c:8
stop only if i == 10
(gdb) r
Starting program: /home/yul/test
The sum of 1-m is 1275
Breakpoint 1, main () at test.c:9
9 n += i;
(gdb) p i
$1 = 10
可以看到,该例中在第8 行(也就是运行完第7 行的for 循环)设置了一个“i==0”的条件断点,在程序运行之后可以看出,程序确实在i为10 时暂停运行。
3.Gdb 中源码查看相关命令
在 Gdb 中可以查看源码以方便其他操作,它的常见相关命令如表3.12 所示。
表3.12 Gdb 源码查看相关相关命令
命令格式 含义
list <行号>|<函数名> 查看指定位置代码
file [文件名] 加载指定文件
forward-search  正则表达式源代码前向搜索
reverse-search  正则表达式源代码后向搜索
dir dir 停止路径名
show directories 显示定义了的源文件搜索路径
info line 显示加载到Gdb内存中的代码
4.Gdb 中查看运行数据相关命令
Gdb 中查看运行数据是指当程序处于“运行”或“暂停”状态时,可以查看的变量及表
达式的信息,其常见命令如表3.13 所示:
表3.13 Gdb 查看运行数据相关命令
命令格式 含义
print 表达式|变量查看程序运行时对应表达式和变量的值
x <n/f/u>   查看内存变量内容。其中n为整数表示显示内存的长度,f表示显示的格式,u表示从当前地址往后请求显示的字节数
display 表达式设定在单步运行或其他情况中,自动显示的对应表达式的内容
5.Gdb 中修改运行参数相关命令
Gdb 还可以修改运行时的参数,并使该变量按照用户当前输入的值继续运行。它的设置方法为:在单步执行的过程中,键入命令“set 变量=设定值”。这样,在此之后,程序就会按照该设定的值运行了。下面,笔者结合上一节的代码将n的初始值设为4,其代码如
下所示:
(Gdb) b 7
Breakpoint 5 at 0x804847a: file test.c, line 7.
(Gdb) r
Starting program: /home/yul/test
The sum of 1-m is 1275
Breakpoint 5, main () at test.c:7
7 for(i=1; i<=50; i++)
(Gdb) set n=4
(Gdb) c
Continuing.
The sum of 1-50 is 1279
Program exited with code 031.
可以看到,最后的运行结果确实比之前的值大了4。
Gdb的使用切记点:
· 在Gcc编译选项中一定要加入“-g”。
· 只有在代码处于“运行”或“暂停”状态时才能查看变量值。
· 设置断点后程序在指定行之前停
posted @ 2014-01-15 15:59 Eric_jiang 阅读(365) | 评论 (2)编辑 收藏

3.4 Gcc 编译器
GNU CC(简称为Gcc)是GNU项目中符合ANSI C 标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。Gcc不仅功能强大,而且可以编译如C、C++、Object C、Java、Fortran、Pascal、Modula-3 和Ada 等多种语言,而且Gcc 又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译。本章中的示例,除非特别注明,否则均采用Gcc版本为4.0.0。
下表3.6 是Gcc支持编译源文件的后缀及其解释。
表3.6 Gcc所支持后缀名解释
后缀名 所对应的语言             后缀名 所对应的语言
.c C原始程序                 .s/.S  汇编语言原始程序
.C/.cc/.cxx        C++原始程序             .h       预处理文件(头文件)
.m                    Objective-C原始程序  .o       目标文件
.i 已经过预处理的C原始程序              .a/.so     编译后的库文件
.ii 已经过预处理的C++原始程序
3.4.1 Gcc编译流程解析
如本章开头提到的,Gcc的编译流程分为了4个步骤,分别为:
· 预处理(Pre-Processing);
· 编译(Compiling);
· 汇编(Assembling);
· 链接(Linking)。
下面就具体来查看一下Gcc是如何完成4 个步骤的。
首先,有以下hello.c源代码:
#include<stdio.h>
int main()
{
printf("Hello! This is our embedded world!\n");
return 0;
}
(1)预处理阶段
在该阶段,编译器将上述代码中的stdio.h编译进来,并且用户可以使用Gcc的选项“-E”进行查看,该选项的作用是让Gcc在预处理结束后停止编译过程。
注意
Gcc指令的一般格式为:Gcc [选项] 要编译的文件 [选项] [目标文件]
其中,目标文件可缺省,Gcc默认生成可执行的文件,命为:编译文件.out
[root@localhost Gcc]# Gcc –E hello.c –o hello.i
在此处,选项“-o”是指目标文件,由表3.6 可知,“.i”文件为已经过预处理的C 原始程序。以下列出了hello.i文件的部分内容:
typedef int (*__gconv_trans_fct) (struct __gconv_step *,
struct __gconv_step_data *, void *,
__const unsigned char *,
__const unsigned char **,
__const unsigned char *, unsigned char **,
size_t *);
# 2 "hello.c" 2
int main()
{
printf("Hello! This is our embedded world!\n");
return 0;
}
由此可见,Gcc确实进行了预处理,它把“stdio.h”的内容插入到hello.i文件中。
(2)编译阶段
接下来进行的是编译阶段,在这个阶段中,Gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言。用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
[root@localhost Gcc]# Gcc –S hello.i –o hello.s
以下列出了hello.s的内容,可见Gcc已经将其转化为汇编了,感兴趣的读者可以分析一下这一行简单的C语言小程序是如何用汇编代码实现的。
.file "hello.c"
.section .rodata
.align 4
.LC0:
.string "Hello! This is our embedded world!"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
subl $12, %esp
pushl $.LC0
call puts
addl $16, %esp
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.0.0 20050519 (Red Hat 4.0.0-8)"
.section .note.GNU-stack,"",@progbits
(3)汇编阶段
汇编阶段是把编译阶段生成的“.s”文件转成目标文件,读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了。如下所示:
[root@localhost Gcc]# Gcc –c hello.s –o hello.o
(4)链接阶段
在成功编译之后,就进入了链接阶段。在这里涉及到一个重要的概念:函数库。读者可以重新查看这个小程序,在这个程序中并没有定义“printf”的函数实现,且在预编译中包含进的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?最后的答案是:系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,Gcc会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的libc.so.6就是动态库。Gcc在编译时默认使用动态库。完成了链接之后,Gcc就可以生成可执行文件,如下所示。
[root@localhost Gcc]# Gcc hello.o –o hello
运行该可执行文件,出现正确的结果如下。
[root@localhost Gcc]# ./hello
Hello! This is our embedded world!
3.4.2 Gcc编译选项分析
Gcc 有超过100 个的可用选项,主要包括总体选项、告警和出错选项、优化选项和体系
结构相关选项。以下对每一类中最常用的选项进行讲解。
(1)总体选项
Gcc的总结选项如表3.7 所示,很多在前面的示例中已经有所涉及。
表3.7 Gcc总体选项列表
-c 只是编译不链接,生成目标文件“.o”
-S 只是编译不汇编,生成汇编代码
-E 只进行预编译,不做其他处理
-g 在可执行程序中包含标准调试信息
-o file 把输出文件输出到file里
-v 打印出编译器内部编译各过程的命令行信息和编译器的版本
-I dir 在头文件的搜索路径列表中添加dir目录
-L dir 在库文件的搜索路径列表中添加dir目录
-static 链接静态库
-llibrary 连接名为library的库文件
对于“-c”、“-E”、“-o”、“-S”选项在前一小节中已经讲解了其使用方法,在此主要讲解另外两个非常常用的库依赖选项“-I dir”和“-L dir”。
· “-I dir”
正如上表中所述,“-I dir”选项可以在头文件的搜索路径列表中添加dir 目录。由于Linux中头文件都默认放到了“/usr/include/”目录下,因此,当用户希望添加放置在其他位置的头文件时,就可以通过“-I dir”选项来指定,这样,Gcc就会到相应的位置查找对应的目录。比如在“/root/workplace/Gcc”下有两个文件:
/*hello1.c*/
#include<my.h>
int main()
{
printf("Hello!!\n");
return 0;
}
/*my.h*/
#include<stdio.h>
这样,就可在Gcc命令行中加入“-I”选项:
[root@localhost Gcc] Gcc hello1.c –I /root/workplace/Gcc/ -o hello1
这样,Gcc就能够执行出正确结果。
小知识
在include语句中,“<>”表示在标准路径中搜索头文件,““””表示在本目录中搜索。故在上例中,可把hello1.c的“#include<my.h>”改为“#include “my.h””,就不需要加上“-I”选项了。
· “-L dir”选项“-L dir”的功能与“-I dir”类似,能够在库文件的搜索路径列表中添加dir 目录。
例如有程序hello_sq.c需要用到目录“/root/workplace/Gcc/lib”下的一个动态库libsunq.so,则
只需键入如下命令即可:
[root@localhost Gcc] Gcc hello_sq.c –L /root/workplace/Gcc/lib –lsunq –o hello_sq
需要注意的是,“-I dir”和“-L dir”都只是指定了路径,而没有指定文件,因此不能在路径中包含文件名。
另外值得详细解释一下的是“-l”选项,它指示Gcc去连接库文件libsunq.so。由于在Linux下的库文件命名时有一个规定:必须以l、i、b 3 个字母开头。因此在用-l选项指定链接的库文件名时可以省去l、i、b 3个字母。也就是说Gcc在对“-lsunq”进行处理时,会自动去链接名为libsunq.so的文件。
(2)告警和出错选项
Gcc的告警和出错选项如表3.8 所示。
表3.8 Gcc总体选项列表
选 项 含 义
-ansi 支持符合ANSI标准的C程序
-pedantic 允许发出ANSI C标准所列的全部警告信息
续表
选 项 含 义
-pedantic-error 允许发出ANSI C标准所列的全部错误信息
-w 关闭所有告警
-Wall 允许发出Gcc提供的所有有用的报警信息
-werror 把所有的告警信息转化为错误信息,并在告警发生时终止编译过程
下面结合实例对这几个告警和出错选项进行简单的讲解。
如有以下程序段:
#include<stdio.h>
void main()
{
long long tmp = 1;
printf("This is a bad code!\n");
return 0;
}
这是一个很糟糕的程序,读者可以考虑一下有哪些问题?
· “-ansi”
该选项强制Gcc生成标准语法所要求的告警信息,尽管这还并不能保证所有没有警告的程序都是符合ANSI C标准的。运行结果如下所示:
[root@localhost Gcc]# Gcc –ansi warning.c –o warning
warning.c: 在函数“main”中:
warning.c:7 警告:在无返回值的函数中,“return”带返回值
warning.c:4 警告:“main”的返回类型不是“int”
可以看出,该选项并没有发现“long long”这个无效数据类型的错误。
· “-pedantic”
允许发出ANSI C标准所列的全部警告信息,同样也保证所有没有警告的程序都是符合
ANSI C标准的。其运行结果如下所示:
[root@localhost Gcc]# Gcc –pedantic warning.c –o warning
warning.c: 在函数“main”中:
warning.c:5 警告:ISO C90不支持“long long”
warning.c:7 警告:在无返回值的函数中,“return”带返回值
warning.c:4 警告:“main”的返回类型不是“int”
可以看出,使用该选项查看出了“long long”这个无效数据类型的错误。
· “-Wall”
允许发出Gcc能够提供的所有有用的报警信息。该选项的运行结果如下所示:
[root@localhost Gcc]# Gcc –Wall warning.c –o warning
warning.c:4 警告:“main”的返回类型不是“int”
warning.c: 在函数“main”中:
warning.c:7 警告:在无返回值的函数中,“return”带返回值
warning.c:5 警告:未使用的变量“tmp”
使用“-Wall”选项找出了未使用的变量tmp,但它并没有找出无效数据类型的错误。
另外,Gcc 还可以利用选项对单独的常见错误分别指定警告,有关具体选项的含义感兴
趣的读者可以查看Gcc手册进行学习。
(3)优化选项
Gcc可以对代码进行优化,它通过编译选项“-On”来控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的Gcc 来讲,n 的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3。
不同的优化级别对应不同的优化处理工作。如使用优化选项“-O”主要进行线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。使用优化选项“-O2”除了完成所有“-O1”级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项“-O3”则还包括循环展开和其他一些与处理器特性相关的优化工作。虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。所以笔者建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。
(4)体系结构相关选项
Gcc的体系结构相关选项如表3.9 所示。
表3.9 Gcc体系结构相关选项列表
选 项 含 义
-mcpu=type 针对不同的CPU使用相应的CPU指令。可选择的type有i386、i486、pentium及i686等
-mieee-fp 使用IEEE标准进行浮点数的比较
-mno-ieee-fp 不使用IEEE标准进行浮点数的比较
-msoft-float 输出包含浮点库调用的目标代码
-mshort 把int类型作为16位处理,相当于short int
-mrtd 强行将函数参数个数固定的函数用ret NUM返回,节省调用函数的一条指令
这些体系结构相关选项在嵌入式的设计中会有较多的应用,读者需根据不同体系结构将
对应的选项进行组合处理。在本书后面涉及到具体实例会有针对性的讲解。
posted @ 2014-01-15 15:21 Eric_jiang 阅读(303) | 评论 (0)编辑 收藏

新规——路考的考试内容有16个项目:
考试上车准备(包括系安全带、观察、打左转灯)、起步、直线行驶、变更车道、通过路口、靠边停车、通过人行横道线、通过学校区域、通过公共汽车站、会车、超车、掉头、夜间行驶、加减挡位操作、路口左转弯、路口右转弯。
posted @ 2014-01-14 09:48 Eric_jiang 阅读(344) | 评论 (1)编辑 收藏

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。
当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。
这样的话,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致,所以就很容易造成一系列的一些安全性问题。
解决此类的方法也有多
1、实现 SingleThreadModel 接口
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。这种方法只要继承这个接口就行了
public class XXXXX extends HttpServlet implements SingleThreadModel {  
…………  
2、同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中可以通过同步块操作来保证Servlet的线程安全。同步后的代码如下:
Public class XXXXXX extends HttpServlet {  
    …………  
synchronized (this){XXXX}  
 
3、避免使用实例变量
线程安全问题还有些是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。
对上面的三种方法进行测试,可以表明用它们都能设计出线程安全的Servlet程序。但是,如果一个Servlet实现了SingleThreadModel接口,Servlet引擎将为每个新的请求创建一个单独的Servlet实例,这将引起大量的系统开销。SingleThreadModel在Servlet2.4中已不再提倡使用;同样如果在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化Servlet 中的同步代码;在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。
小结
Servlet的线程安全问题只有在大量的并发访问时才会显现出来,并且很难发现,因此在编写Servlet程序时要特别注意。线程安全问题主要是由实例变量造成的,因此在Servlet中应避免使用实例变量。如果应用程序设计无法避免使用实例变量,那么使用同步来保护要使用的实例变量,但为保证系统的最佳性能,应该同步可用性最小的代码路径。
posted @ 2014-01-07 11:13 Eric_jiang 阅读(226) | 评论 (0)编辑 收藏

下面是switch的简单写法:
switch(A){
case B;
}
A部分中的值必须是int型的,或者是能够自动进行饮试转换成int型的表达式。也就是说A部分可以是byte/short/char/int型的。
其次要强调的是该程序中B部分的值必须是单个byte/short/char/int型的值,或者是final型的变量。
但是final型的变量也是有要求的,也即是它必须是编译时的常量,怎么讲呢,看下面的程序段:
final int a = 0;
final int b;
第二个语句就是在编译时不能够被识别出值的变量,因为它没有初始化,当然,这条语句也是错误的。
所以总结case后的值可以是常数值或final型的值。

再看下面的程序段:

public class TestSwitch {
public static void main(String[] args){
byte a = 11;
switch(a){// C
case 11 : System.out.println(" 11 "); break;
case 225 : System.out.println(" 11 "); break;// D
}
}
}

该代码正确吗?答案是否定的。虽然在 C 处是合法的也即是byte型的a值可以出现在switch中,但是 D处的语句也即是第二个case后的值是225大小超过了byte的范围,所以是错误的。再就是case后的值不能出现重复。因此在使用中要注意。

=====================
再就是在使用switch-case中最容易忽视的就是忘记在每个case后处理完后忘记写上break;语句。那它带来的后果是什么呢,下面小程序段会告诉你:
public class TestSwitchCase {
public static void main(String[] args){
byte a = 2;
switch(a){
case 1 : System.out.println(" A ");
case 2 : System.out.println(" B ");
case 3 : System.out.println(" C ");
case 4 : System.out.println(" D ");
                default : System.out.println(" default ");
}
}
}
=========输出结果为:
 B 
 C 
 D 
 default 
--------------------------
看到了吗?连default都执行,注意结束符break;就OK了。
posted @ 2014-01-06 14:59 Eric_jiang 阅读(316) | 评论 (0)编辑 收藏

仅列出标题
共57页: First 上一页 10 11 12 13 14 15 16 17 18 下一页 Last