并行处理通信交流
返回码对软件性能至关重要,但它们仅在单个SAS会话中可行。一旦会话终止,返回码和其他所有的宏变量均会消除。在使用SYSTASK命令大量生产批作业的复杂软件设计中,或者在 SAS会话并行运行且必须相互交流的运行环境中,返回码是无 用的。相反,交叉会话交流需要互斥、信号量、控制表及SYSPARM参数。第 11章将介绍并行处理中存在的其他通信交流复杂性。
互斥和信号量
信号量是一个通过指示某个动作已经完成或者某个事件已经发生来实现并行程序同步化的共享变量。信号量是标识,代表软件中的事件或条件,且通常由变量表示。在 SAS软件中,由于宏变量不能被多个 SAS程序读取,因此,必须使用文件或数据集作为各个会话之间传递信息的信号量,类似于海军舰艇之间传递的旗帜信号。信号量最常见的用途之一是标示某个对象是处于可供使用的状态还是正在使用的状态。
在某些情况下,一个对象一次仅能供一个程序使用,例如,当要求专用锁定用于获取和修改某个SAS数据集时。互斥信号量(或互斥量)代表一类信号量,这类信号量能确保某些对象的互斥访问,且被定义为“一个实现互斥的机制”。互斥量不仅能确保当前数据集的使用是被标记的,还能确保其他程序在标记被检测到的情况下无法干扰其使用。在前述“&SYSLCKRC”部分LOCK程序指令中,由于存在不一致性,因此,需要用互斥来独家锁定一个数据集以促进并行处理中会话之间的通信交流。
在本例中,“互斥”是一个创建的空白文本文件,同样命名为一个数据集。如果存在“互斥”(如文本文件)且其未被任何SAS会话锁定,那么当前SAS会话将锁定该“互斥”,随后便能够安全地访问相关的数据集;若不需要数据集访问,“互斥”锁定就会被解除。如果SAS会话遇到一个被锁定的“互斥”,那么异常情况处理将阻止对相关数据集的访问。这一逻辑使两个或多个并发的SAS会话轮流获取数据集,而无须担心出现文件访问冲突或“运行时错误”。
在 SAS 的一个会话中运行以下代码以说明“互斥”的用途。
libnameperm'c:\perm';
dataperm.test;lengthchar1$10;
run;
%macromutex(dsn=/*inLIB.DSNformat*/,cnt=/*numberofiterationstorun*/);
%locallib;
%localtab;
%localclosed;
%localdsid;
%letlib=%scan(&dsn,1);
%lettab=%scan(&dsn,2);
%letloc=%sysfunc(pathname(&lib))\&tab..txt.lck;
filenamemyfil"&loc";
%doi=1%to&cnt;
%letdsid=%sysfunc(fopen(myfil,u));
%if&dsid>0%then%do;
data&dsn;set&dsn;
run;
%letclosed=%sysfunc(fclose(&dsid));
%end;
%end;
%mend;
%mutex(dsn=perm.test,cnt=1000);
在另一个 SAS会话中,立即执行 LIBNAME程序指令和%MUTEX宏(但不是DATA步骤),以便使两个会话并行运行。程序将创建“互斥”(文本文件C:\perm\ test.txt.lck),两个会话会不断地试验该“互斥”以获取PERM.Test数据集。只有当一个会话能独家锁定“互斥”时,才能执行后续的 DATA 步骤,从而防止因访问冲突而出现的“运行时错误”。
控制表
控制表指的是从外部存储到程序代码中的数据,该程序代码的作用是帮助数据驱 动处理过程,通常是促进双向交流——软件把数据写入控制表同时也从中读取数据。 在 SAS文献中,控制表有时也称为“控制数据集”。这是 SAS专用术语,该术语不使用相关数据库术语“表”而是使用“数据集”。除了包含动态驱动程序流的数据之外,某些控制表还收集过程中的性能指标,有时反过来还会使用这些指标来驱动下一个处 理程序。因此,尽管一些控制表包含足够的信息指示程序流,但有些控制表还会包含 以往的性能数据。第 7章中的表 7-1及第 9章中的表 9-1展示了控制表示例。
控制表和配置文件均能动态驱动程序流,增强灵活性,减少硬编码,提升可用性。然而,配置文件是比较重要的,因为通信流只能从配置文件装入软件。另外,通常仅 在软件初始化过程中读取配置文件,而控制表在软件运行的整个过程中均可以读取。 配置文件更倾向于手动更新,这样一来,软件在下次运行的过程中会产生不同的结果,而控制表通常是在软件运行过程中创建和修改的。第 17章会介绍配置文件。
由于宏变量不能在并行运行的独立 SAS会话中传输,因此,控制表能够促进交叉会话之间的交流,使每个会话中的软件在同一控制表中轮流丢弃和检索信息。数据集的修改要求专用锁定,而且如果两个以上的用户或程序试图同时访问同一个 SAS数据集,便会出现文件访问冲突。基于以上两个原因,并行程序运行中必须执行“互 斥”以避免冲突和“运行时错误”。“互斥”在前面部分已做介绍。在第 7 章会讲述使用控制表支撑并行处理。
控制表的另一个用途是将数据和元数据从子进程返回到父进程。若 SYSTASK程序指令用于创建批处理流程,除父进程之外,子进程会在一个新的SAS会话中大量生成。尽管父进程能够通过SYSPARM参数将信息传达给子进程(下一部分介绍),但子进程无法越过会话边界将数据或元数据返回到父进程中。出于这个原因,与控制 表促进并行处理的方法相类似,子进程批量处理过程能将数据和元数据汇总到一个控 制表中,父进程稍后可检索该控制表以验证批量程序的顺利执行,并检索其他数据或 输出信息。
当一个批处理流程在SYSTASK大量生产且子进程出现警告或“运行时错误”,父进程将会通过&SYSRC 宏变量获得这一信息。&SYSRC 宏变量在前面已讲过。另外,第 11章会对该变量进行详细介绍。由于跟在SYSTASK后面的 &SYSRC数值有限,能够传达的有效信息较少,自定义异常情况处理框架通常必须能够检测和回应批处理 过程出现的警告或“运行时错误”。