文章
· 六月 30, 2022 阅读大约需 2 分钟

第十四章 信号(四)- 多进程任务示例

第十四章 信号(四)- 多进程任务示例

可根据此思想进行多任务启动查询汇总数据。

原理

  • 利用job机制开启后台进程。
  • 利用loop循环减少进程的数量等于开启进程的数量,判断多进程任务是否完成。
  1. 创建表并插入1000W条数据,统计Moeny字段总金额

  2. 创建demo代码如下。

Class Demo.SemaphoreDemo Extends %RegisteredObject
{

///  Do ##class(Demo.SemaphoreDemo).Sample(5)
ClassMethod Sample(pJobCount = 3)
{
    k ^yx("Amt"),^yxAmt

     /* 1.启动信号 */
    s mSem = ##class(Demo.Sem).%New()
    If ('($isobject(mSem))) 
    {
        q "启动失败"
    }

    /* 2. 初始化信号量为0 */
    d mSem.Init(0)

    s t1 = $zh

    /* 3. 按指定数量,启动后台任务 */
    for i = 1 : 1 : pJobCount
    {
        j ..Task(i)
    }

    w "启动job时间:"_ ($zh - t1),!

    /* 4. 等待后台任务完成 */
    s tCount = i,tSC = 0
    /* 后台任务完成的判断条件是:减少的信号量=总后台任务数 */
    while (tSC < tCount)
    {
        s tSC = tSC + mSem.Decrement(tCount, 10)
    }

    w "完成时间:"_ ($zh - t1),!


    s moneyAmt = 0


    s data = ""
    for {
        s data = $o(^yxAmt(data))
        q:(data = "")
        s moneyAmt = moneyAmt + ^yxAmt(data)
    }
    d mSem.Delete()
    w "总金额" _ moneyAmt,!

    w "汇总时间:"_ ($zh - t1),!
    q
}

ClassMethod Task(i)
{
    s tSem = ##class(Demo.Sem).%New()
    s moneyAmt = 0
    for j = (i * 100000) + 1 : 1 : (i + 1) * 100000 {
        s money = $li(^M.YxPersonD(j), 3)
        s moneyAmt = moneyAmt + money
    }
    s ^yxAmt("moneyAmt" _ i) = moneyAmt
    s ^yx("Amt") = $i(^yx("Amt"))
    d tSem.Open(##class(Demo.Sem).Name())
    d tSem.Increment(1)
    d tSem.%Close()
    q moneyAmt
}
}
  1. 创建信号类,定义name和初始化信号方法。
Class Demo.Sem Extends %SYSTEM.Semaphore
{

ClassMethod Name() As %String
{
    q "Semaphore"
}

Method Init(initvalue = 0) As %Status
{
    try {
        If (..Create(..Name(), initvalue)) {
            ret 1
        } else {
            ret 0
        }
    } catch {
        ret 0
    }
}

}
  1. 调用
DHC-APP>Do ##class(Demo.SemaphoreDemo).Sample(5)
启动job时间:.098982
完成时间:.119744
总金额250088825096472
汇总时间:.119774
讨论 (0)1
登录或注册以继续