# 第十四章 信号(四)- 多进程任务示例 > 可根据此思想进行多任务启动查询汇总数据。 # 原理 - 利用`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 } } ``` 3. 创建信号类,定义`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 } } } ``` 4. 调用 ``` DHC-APP>Do ##class(Demo.SemaphoreDemo).Sample(5) 启动job时间:.098982 完成时间:.119744 总金额250088825096472 汇总时间:.119774 ```