使应用程序线程安全

使应用程序线程安全时,您可以使用开放式事务环境,避免 TCB 切换,并且获得性能优势。

开始之前

要使用线程安全应用程序,请确保系统初始化参数 FORCEQR 未设置为 YES。 FORCEQR 强制定义为线程安全的程序在 QR TCB 上运行,并且在调查并解决与线程安全定义的程序相关的问题时,可以将其设置为 YES 作为临时度量。

此外,请在拥有文件的 CICS® 区域中为系统初始化参数 FCQRONLY 选择适当的设置。 如果 FCQRONLY 设置为 YES ,那么 CICS 将强制 CICS 区域中的所有文件控制请求在 QR TCB 上运行。
  • 如果使用 IPIC 连接将文件控制请求传递到远程 CICS TS 4.2 或更高版本区域,那么要提高这些连接的性能,请在文件拥有区域中将 FCQRONLY 设置为 NO。
  • 如果仅使用基于 SNA 连接的 MRO 链接或 ISC ,或者文件拥有区域早于 CICS TS 4.2 ,请在文件拥有区域中将 FCQRONLY 设置为 YES。

如果要使用 CICS 相互通信来请求在远程 CICS 系统中运行的功能或程序,请在 CICS 系统之间选择基于 TCP/IP 连接的 IP 互连 (IPIC) ,以提供对线程安全应用程序的最佳支持。 通过 IPIC 连接, CICS 使用开放式 TCB 来运行用于在远程 CICS 系统上管理请求的镜像程序,从而提高吞吐量。 对于其他连接类型, CICS 不会使用开放式 TCB 来运行镜像程序。 EXEC CICS LINK 命令用于分布式程序链接 (DPL) ,对于与远程 CICS 区域 (其中使用了长时间运行的镜像) 的 IPIC 连接是线程安全的,但不适用于其他连接类型。

关于此任务

线程安全程序 说明了程序线程安全的含义,以及在开放式 TCB 和 QR TCB 之间进行 TCB 切换的情况。

要使应用程序成为线程安全的应用程序并使其能够保留在开放式 TCB 上,请使用以下过程。

过程

  1. 通过在 PROGRAM 资源定义中指定 CONCURRENCY(THREADSAFE) ,将程序定义为线程安全的 CICS 。

    对于定义为 OPENAPI 的程序, CICS 需要 CONCURRENCY(THREADSAFE) 选项。 仅允许已定义为线程安全的代码在开放式 TCB 上运行。 通过将 CICS 的程序定义为线程安全程序,您仅指定应用程序逻辑是线程安全的,而不是指定程序中包含的所有 EXEC CICS 命令都是线程安全的。 CICS 可以确保通过使用 TCB 切换来安全地处理 EXEC CICS 命令,但是,为了允许程序在开放式 TCB 上运行, CICS 需要您保证应用程序逻辑是线程安全的。

    或者,您可以将程序定义为 CONCURRENCY(REQUIRED) ,以使程序能够从一开始就在开放式 TCB 上运行。 定义为 CONCURRENCY(REQUIRED) 的程序必须编码为线程安全标准,因为它们必须始终在开放式 TCB 上运行。 使用的开放式 TCB 类型取决于 API 设置。

  2. 确保程序逻辑 (即 EXEC CICS 命令之间的本机语言代码) 是线程安全的。

    如果将 CICS 的程序定义为线程安全,但包含非线程安全的应用程序逻辑,那么结果不可预测,并且 CICS 无法保护程序免受可能的后果影响。 要使程序逻辑成为线程安全的,在访问共享资源时必须使用相应的序列化方法,以禁止对这些资源的并发访问。 使用 EXEC CICS 命令访问资源 (例如,文件,瞬时数据队列,临时存储器队列和 DB2® 表) 时, CICS 确保线程安全处理,但对于用户程序直接访问的任何资源 (例如,共享存储器) ,用户程序必须确保线程安全处理。

    共享存储器的典型示例包括 CICS CWA ,全局用户出口的全局工作区以及应用程序使用共享选项显式获取的存储器。 通过查找出现的以下 EXEC CICS 命令,检查应用程序是否使用这些类型的共享存储器:
    • 地址 CWA
    • EXTRACT EXIT
    • Getmain 共享
    装入模块扫描程序实用程序包含样本表 DFHEIDTH ,以帮助您识别允许访问共享存储器的 CICS 命令。 虽然其中一些命令本身是线程安全的,但它们都允许访问全局存储区域,因此遵循这些命令并使用全局存储区域的应用程序逻辑可能不是线程安全的。 为了确保它是线程安全的,应用程序必须包含必要的同步逻辑以防止并发更新。
    提示: 识别使用共享资源的程序时,还包括修改其自身的任何程序。 此类程序正在有效共享存储器,您必须将其视为存在风险。
    您可以使用以下方法在访问共享资源时提供线程安全处理:
    • 如果资源已由另一个程序使用比较和交换指令同时更改,请重试访问。
    • 在资源上排队,以获取互斥控制,并确保没有其他程序可以使用下列其中一种方法访问该资源:
      • 应用程序中的 EXEC CICS ENQ 命令。
      • 对全局用户出口程序中的 CICS 入队 (NQ) 域的 XPI ENQUEUE 函数调用。
      • 仅当启用了 L8 TCB 以供使用时,开放式 API 任务相关用户出口中的 MVS™ 服务 (例如 ENQ)。 请注意,在可以在 QR TCB 下运行的应用程序中使用 MVS 服务可能会导致性能下降,因为 TCB 处于等待状态。
    • 通过使用 EXEC CICS LINK 命令链接到拟重入程序,仅在定义为拟重入的程序中执行对共享资源的访问。 此技术仅适用于线程安全应用程序和开放式 API 任务相关的用户出口。 定义为准重入程序的链接至程序在 QR TCB 下运行,并且可以利用 CICS 拟重入提供的序列化。 请注意,即使在拟重入方式下,仅在程序保留控制权且不等待的情况下才会提供序列化。
    • 将访问共享资源的所有事务放入受限事务类 ( TRANCLASS ) 中,该事务类是使用指定为 MAXACTIVE(1) 的活动任务数定义的事务类。 这种方法有效提供了非常粗的锁定机制,但可能会对性能造成严重影响。
    注: 虽然术语 threadsafe 是在各个程序的上下文中定义的,但仅当访问共享资源的所有应用程序都遵守规则时,作为一个整体的用户应用程序才能被视为 threadsafe。 如果另一个访问相同资源的程序不遵守线程安全规则,那么正确写入线程安全标准的程序无法安全地更新共享资源。
  3. 为了获得最佳性能,请确保程序仅使用线程安全 EXEC CICS 命令。

    如果在定义为线程安全且在开放式 TCB 上运行的程序中包含非线程安全的 EXEC CICS 命令,那么 CICS 会从开放式 TCB 切换回 QR TCB ,以确保安全地处理该命令。 应用程序的结果不受影响,但其性能可能会受影响。

    在 CICS API 和 SPI 命令主题的命令描述中使用 此命令是线程安全的 语句来指示线程安全的命令。 它们也列示在 Threadsafe 命令Threadsafe SPI 命令中。

    装入模块扫描程序实用程序包含样本表 DFHEIDNT ,用于帮助识别应用程序中任何非线程安全的 CICS 命令。

  4. 如果任何用户出口程序位于程序所使用的执行路径中,那么为了获得最佳性能,请确保这些程序也编码为线程安全标准,并将 CICS 定义为线程安全。 这些出口可以是动态计划出口,全局用户出口或与任务相关的用户出口。 另外,请检查由任何供应商软件提供的用户出口程序是否已按线程安全标准进行编码,并将 CICS 定义为线程安全程序。

    线程安全用户出口程序可以在与调用该程序的线程安全应用程序相同的开放式 TCB 上使用,并且可以使用非 CICS API ,而不必创建和管理子任务 TCB ,并为自身利用开放式事务环境。 如果程序所使用的执行路径中的任何用户出口程序都不是线程安全的,那么 CICS 会切换到 QR TCB 以运行这些程序,这可能会损害应用程序的性能。

    请注意以下重要用户出口:
    • EXEC CICS 命令前后调用全局用户出口 XEIIN 和 XEIOUT。
    • 在定义到 CICS 的程序接收控制之前,将调用全局用户出口 XPCFTCH。
    • 对于 CICS DB2 请求, CICS DB2 任务相关的用户出口 DFHD2EX1 是线程安全的。 CICS DB2 请求的其他重要出口包括缺省动态计划出口 DSNCUEXT (未定义为线程安全) ,备用动态计划出口 DFHD2PXT(定义为线程安全) 以及全局用户出口 XRMIIN 和 XRMIOUT。
    • 如果通过 IPIC 连接将 CICS 文件控制,瞬时数据或临时存储器请求交付到远程 CICS 区域,那么这些请求是线程安全的,可以在开放式 TCB 上的远程 CICS 区域中运行。 在远程 CICS 区域中针对文件控制,瞬时数据或临时存储器请求调用的任何全局用户出口程序都必须作为线程安全程序启用,以实现最佳性能。
    1. 要将 CICS 的用户出口程序定义为线程安全程序,可以在其 PROGRAM 资源定义中指定相应的属性。
      • 对于与任务相关的用户出口程序,指定 OPENAPI 和 THREADSAFE 或仅指定 THREADSAFE。
      • 对于全局用户出口程序,不能使用 OPENAPI ,但可以指定 THREADSAFE。

      如果在全局用户出口程序或与任务相关的用户出口程序上指定 CONCURRENCY (REQUIRED) ,那么 CICS 会将该程序视为已指定 CONCURRENCY(THREADSAFE)

    2. 或者,要将 CICS 的用户出口程序定义为线程安全程序,可以在使用 EXEC CICS ENABLE PROGRAM 命令启用该程序时指定相应的选项。
      • 对于与任务相关的用户出口程序,请指定 OPENAPI 或 THREADSAFE。
      • 对于全局用户出口程序,不能使用 OPENAPI ,但可以指定 THREADSAFE。
      使用 OPENAPI 或 THREADSAFE 选项启用出口程序时,此操作向 $TAG1 CICS $TAG2 指示程序逻辑是线程安全的,因此 $TAG3 CICS $TAG4 会覆盖出口的程序定义上的 CONCURRENCY 设置,并将出口程序视为线程安全的。
    3. 要将第一阶段 PLT 全局用户出口程序定义为线程安全程序,请在 EXEC CICS ENABLE PROGRAM 命令上指定 THREADSAFE。
      为确保全局用户出口程序 (例如在恢复出口点运行的程序) 在 CICS 初始化期间尽早可用,通常会从第一阶段 PLT 程序启用这些程序。 因为第一阶段 PLT 程序在 CICS 初始化过程中运行这么早,所以不能使用已安装的 PROGRAM 资源定义或程序自动安装用户程序来定义出口程序。 CICS 使用 CONCURRENCY(QUASIRENT) 自动安装从第一阶段 PLT 程序启用的出口程序。 但是, EXEC CICS ENABLE PROGRAM 命令上的设置将覆盖系统自动安装的程序定义上的 CONCURRENCY(QUASIRENT) 设置。