- 论坛徽章:
- 0
|
本帖最后由 niuhua77 于 2011-07-12 18:33 编辑
一 基本概念:
Service program是由module和其他Service program组成的,在系统中用*SRVPGM来表示(好像是废话- -!),其包含了很多可被其他程序调用的procedure。
Service program是用by reference方式绑定,功能类似于其他语言的函数库,提供了很多procedure供其他ILE program调用。
Service program中哪些procedure可以被其他program调用,哪些不可以呢?这就牵扯到了Service program中一个非常重要的概念:public interface。
二 公共接口(public interface)
Service program的public interface规定了哪些procedure和data item可以被外界使用,哪些不可。如果public interface设置的不合理,很容易产生program与Service program不兼容的问题,导致程序发生异常。那么如何定义Service program的public interface呢,如下:
CRTSRVPGM命令的EXPROT参数规定了Service program如何对外提供接口,并提供2个参数值:
1 EXPORT (*ALL)。选择*all的话,那么Service program里所有使用key word:EXPORT修饰的procedure和data item都可以被外界程序使用。
2 EXPROT(*SRCFILE)。*SRCFILE是默认的参数值。使用*SRCFILE的话,可以使用binder language(BND文件)来自定义public interface,自己选择哪些procedure和data item可以被外界使用(这些 procedure、data item也必须使用key word:EXPROT修饰)。
注:binder language的文件类型是BND,默认的SOURCE FILE是QSRVSRC,并且BND文件是不需要编译的。
下面说一下*ALL和*SRCFILE各自的优缺点:
*ALL的优点:使用起来非常方便,不需要额外的辅助文件,Service program中所有的export procedure 和data item就都可以被其他程序调用。
*ALL的缺点:兼容性太差,无论增加或者减少Service program的export procedure、data item,都会导致program与Service program的不兼容。那么所有用到此Service program的program都需要重新绑定(UPDPGM)或者重新编译(CRTPGM)才能正常使用。就算是这种变化并不会影响程序的正常运行(比如说你向Service program中追加了一个新的procedure,并且现程序并不使用此procedure,即增加procedure不影响现在的程序运行)那么所有用到此Service program的program也要重新绑定或编译。很麻烦吧。
*SRCFILE的缺点:*SRCFILE使用起来要比*ALL麻烦些,因为要使用binder language定义BND文件才能使用。
*SRCFILE的优点:提供了很好的兼容性。即增加或者减少Service program 的 export 的procedure、data item,程序仍然运行,不需要重新编译相关的program。
那到底是什么原因产生的兼容性问题?听我慢慢道来
三 signature与binder language
1 signature
首先系统为Service program提供了一个类似PF的level check的功能,来检查ILE program与Service program当前的接口是否一致。大概的过程如下:
1)CRTSRVPGM时,系统会根据Service program 的export procedure、data item的数量、名称、顺序产生一个signature(类型于PF的record format ID,具有唯一性),并保存在*SRVPGM中。例如:
DSPSRVPGM SRVPGM(PASS) DETAIL(*SIGNATURE)
splay Service Program Information
Display 1 of 1
Service program . . . . . . . . . . . . : PASS
Library . . . . . . . . . . . . . . . : MYLIB
Owner . . . . . . . . . . . . . . . . . : MYLIB
Service program attribute . . . . . . . : RPGLE
Detail . . . . . . . . . . . . . . . . . : *SIGNATURE
Signatures:
0000000000000000C5F03F1A5845D322
2)CRTPGM时,会将此Service program绑定到*PGM中,同时会把Service program当前的signature值也保存在*PGM中。例如:
DSPPGM PGM(PASSBY2) DETAIL(*SRVPGM)
Display Program Information
Service
Opt Program Library Signature
PASS *LIBL 0000000000000000C5F03F1A5845D322
QRNXIE QSYS D8D9D5E7C9C540404040404040404040
QRNXUTIL QSYS D8D9D5E7E4E3C9D34040404040404040
QLEAWI QSYS 44F70FABA08585397BDF0CF195F82EC1
3)当*PGM被调用的时候,PGM会激活Service program(即把Service program加入到active group中),在激活的过程中会比较*PGM中的signature值与*SRVPGM的signature值是否一致。如果一致,则程序正常运行;如果不一致,则程序出现异常。
大概就这么个过程。
2 与PF LEVEL CHECK(*YES/*NO)类似,你也可以指定是否进行signature的检查
1)*ALL的话,默认LVLCHK(*YES)并且不能更改,会进行检查。那么当Service program的export procedure、data item发生变化时(增加、减少),相应的signature值也发生变化了,如果不重新绑定,重新编译相关的program,那么就导致了program与Service program的signature值不一样,必然导致不兼容。
2)*SRCFILE的话,可以选择LVLCHK *YES还是*NO。选择*NO的话,就不用细说了,因为*NO不会进行signature检查无论你怎么变化procedure、data item都不要紧。因为系统根本不会对program与Service program的signature进行对比,自然不存在兼容不兼容的问题。(使用*NO要谨慎,没有系统的检查,可能会出现一下不可预知的错误)
选择*YES的话,你可以在一个BND文件中,定义多个signature,只要*PGM中保存的signature值与BND文件中任意一个signature值相当,程序就可以正常运行。举个例子吧:
PGM1用到了SRVPGM1
SRVPGM1有2个export procedure:export P1 export P2
BND文件:
STRPGMEXP PGMLVL(*CURRENT) LVLCHK(*YES)
EXPORT SYMBOL(‘P1’)
EXPORT SYMBOL(’P2’)
ENDPGMEXP
假设经过编译后,PGM1可以正常调用SRVPGM1。
现在SRVPGM1增加了一个export procedure,那么为了保持PGM1与SRVPGM1的兼容,我会增加一个signature,如下:
BND文件:
STRPGMEXP PGMLVL(*CURRENT) LVLCHK(*YES)
EXPORT SYMBOL(‘P1’)
EXPORT SYMBOL(’P2’)
EXPORT SYMBOL(’P3’)
ENDPGMEXP
STRPGMEXP PGMLVL(*PRV) LVLCHK(*YES)
EXPORT SYMBOL(‘P1’)
EXPORT SYMBOL(’P2’)
ENDPGMEXP
这样的话,即使我不重新编译PGM1,PGM1也可以正常调用SRVPGM1(不过不能使用新追加的P3,只能使用*PRV的export block)
注意:signature的值是由export procedure、data item的名称、数量、顺序决定的,且具有唯一性。为了避免不兼容问题的发生,注意以下几点:
1)不要破坏原来export block中export procedure、data item的顺序和数量。
2)新追加export block(即定义多个signature)的话,新的export block必须要包含原来的export block中的内容,并且顺序、数量都不能改变。新追加的export procedure、data item要放export list的最后面。(如上面例子所示)
3)不要删除原export block中的procedure、data item
此外,还可以通过自定义signature的值,也可以解决兼容性问题,这里就不多说了。
四 service program的激活
Service program不能够直接激活。调用SRVPGM的ILE PROGRAM被调用的话,那么此SRVPGM就自动被激活。
Service program的激活过程中,主要干2件事:
1 通过符号链接与物理地址的转换,完成绑定工作。
2 进行signature checking。
这两步之前都进行过详细说明,不再叙述。
—————————————补充说明————————————————————————————————————————————————————
五 service program的用途、目的、优势
为什么要使用service program呢?service program能给我们提供什么好处呢?
我们之所以选择service program,主要从以下2方面进行考虑:
1 采用service program,能使系统维护更加方便,提高可重用性(我认为是最主要的原因)
2 采用service program,可以节省硬盘空间,节省内存空间。
下面还是摆事实、讲道理吧
1) 可维护性:
假如说有N个程序,都会调用MOD1,不使用service program方式的话,就得使用by copy的方式绑定,即:CRTPGM (PGM1) MODULE(MOD1)。那么,如果MOD1发生变更的话,这N个程序都需要重新绑定(UPDPGM)或者编译(CRTPGM),才能使用更新后的MOD1。
如果使用service program的话,把MOD1加入到SRVPGM1中。当MOD1再次发生变更时,如果MOD1的变更不影响SRVPGM1的public interface(即PGM1与SRVPGM1仍然兼容),那么你只需要UPDSRVPGM即可,其他相关联的N个程序都不需要重新绑定或编译;如果MOD1的变更影响到了SRVPGM1的public interface的话(比如说MOD1新增加了一个export procedure,即PGM1与SRVPGM1不兼容),那么你UPDSRVPGM之后,也只需要UPDPGM(或CRTPGM)与新追加的export procedure相关的PGM即可,不需要UPDPGM所有的PGM,方便吧。
2)节省空间:
使用by copy的方式绑定,N个程序中就有N个MOD1的代码。如果使用service program,那么整个硬盘中实际上只有一个MOD1的代码,节省了硬盘空间。
而在实际运行中,所有的用户实际上是共用一份service program的代码,系统会给每个用户分配独立的静态变量区,但是代码是共用一份的。而使用by copy的方式,每个程序中,还是会包含一分MOD1的代码,这样service program也就节省了内存空间。
六 实际使用情况
如果一个procedure被多个程序调用的话,那么就应该把它加入到service program中。如果这个procedure仅仅是一次性使用的话,那么就没必要了。
我认为理想的情况是,ILE *PGM应该由一个main procedure/module(提供PEP)+ 其它service program组成。
具体的应用情况是,可以把功能类似的程序组成一个service program。比如把各种登录验证的程序,归为一个service program;各种日期转换,日期编辑的程序放到一个service program;还有各种处理代码程序,放到一个service program等。
每个公司的应用情况都不同,欢迎其他的同学可以补充,指正。 |
|