CBL_THREAD_CREATE で作成されたスレッドは、CBL_THREAD_KILL ルーチンで取り消すことができます。CBL_THREAD_KILL を使用して、別の方法で作成されたスレッドを強制終了することはできません。この場合には、COBOL スレッドはただちに異常終了されますが、通常は、CBL_THREAD_KILL を一般的なアプリケーション スレッド コントロールの一部として使用しないでください。主な理由は、スレッドの終了時に、ユーザーとシステムの同期リソースが、正しくロック解除または解放されないためです。そのため、ユーザー アプリケーションとランタイム システム間の同期が影響を受け、アプリケーションで重大な問題が発生することがあります。
CBL_THREAD_KILL は、主スレッドの重大エラー ハンドラーでは、適切に使用できます。このエラー ハンドラーでは、スレッド ハンドルを CBL_THREAD_LIST_n ルーチンによって獲得できます。スレッドをすべて取り消し、STOP RUN でアプリケーションを終了します。この方法では、同期プリミティブをロックする必要性が最小限になるため、CBL_THREAD_KILL のランダム使用に比べると危険ではありません。ただし実行単位の終了時に、ファイル破壊やデッドロックが発生する可能性はあります。
いずれにせよ、ほとんどのアプリケーションでは CBL_THREAD_KILL を使用しないようにしてください。そのためには、終了フラグをもつスレッド識別データを作成 (CBL_THREAD_IDDATA_ALLOC ルーチンを使用) します。そのデータは、ロックが保持されていないレベルの各スレッドでポーリングできます。終了フラグが設定されている場合は、ポーリング スレッドを正常に終了できます。
例 - スレッド識別データと終了フラグの作成
******************** MAINPROG.CBL ********************
identification division.
program-id. mainprog.
Data Division.
Local-Storage Section.
01 ret-ptr usage pointer.
01 iddata-ptr usage pointer.
01 sub-iddata-ptr usage pointer.
01 sub-handle usage thread-pointer.
Linkage Section.
01 iddata-record.
05 iddata-name pic x(20).
05 iddata-term pic x comp-x value 0.
Procedure Division.
* Establish identification data - don't provide
* initialization data when it is allocated, instead
* initialize it after the pointer is retrieved.
call 'CBL_THREAD_IDDATA_ALLOC' using
by value zero
length of iddata-record
call 'CBL_THREAD_IDDATA_GET' using iddata-ptr
omitted
set address of iddata-record to iddata-ptr
move 'main' to iddata-name
* Create sub-thread
* Starting point
call 'CBL_THREAD_CREATE' using
'SUBPROG '
by value 0 *> No parameters
0 *> Optional - parameter size
0 *> Flag to create detached
0 *> Default priority
0 *> Default stack
by reference sub-handle
if return-code not = 0
display 'unable to create thread'
stop run
end-if
* Wait until child creates its iddata and then flag
* termination
set sub-iddata-ptr to NULL
perform until 1 = 0
call 'CBL_THREAD_IDDATA_GET'
using sub-iddata-ptr
by value sub-handle
end-call
if sub-iddata-ptr not = null
exit perform
end-if
call 'CBL_THREAD_YIELD'
end-perform
set address of iddata-record to sub-iddata-ptr
move "stop" to iddata-name
move 1 to iddata-term
* Wait till the child exits
wait for sub-handle
display 'All synchronization is complete on ' &
'RTS termination'
stop run.
end program mainprog.
*************** SUBPROG.CBL ********************************
identification division.
program-id. subprog.
Data Division.
Working-Storage Section.
01 sub-iddata.
05 sub-name pic x(20) value 'sub'.
05 sub-term pic x comp-x value 0.
Local-Storage Section.
01 iddata-ptr usage pointer.
01 thread-handle usage pointer.
01 thread-state pic x(4) comp-x.
01 parent-handle usage pointer.
Linkage Section.
01 iddata-record.
05 iddata-name pic x(20).
05 iddata-term pic x comp-x value 0.
Procedure Division.
* Establish identification data - provide initialization data
call 'CBL_THREAD_IDDATA_ALLOC' using
sub-iddata
by value length of sub-iddata
* Find our parent thread and resume him
*
call 'CBL_THREAD_LIST_START' using thread-handle
thread-state
iddata-ptr
set parent-handle to NULL
perform until thread-handle = null
or return-code not = 0
if iddata-ptr not = null
set address of iddata-record to iddata-ptr
if iddata-name = 'main'
set parent-handle to thread-handle
exit perform
end-if
end-if
call 'CBL_THREAD_LIST_NEXT' using thread-handle
thread-state
iddata-ptr
end-perform
call 'CBL_THREAD_LIST_END'
if parent-handle = NULL
display 'synchronization error'
stop run
end-if
call 'CBL_THREAD_IDDATA_GET' using iddata-ptr
omitted
set address of iddata-record to iddata-ptr
perform until iddata-term = 1
call 'CBL_THREAD_YIELD'
end-perform
exit program.
end program subprog.
この長めのコード例では、実際にはスレッドとアプリケーションの終了について、ハンドシェイクを確立するのみです。これについて説明する前に、主スレッドのハンドルをパラメーターとして子スレッドに渡せば、このようなハンドシェイクの確立をより簡単に行えることに注目する必要があります。この方法を使用すると、識別データに依存したり、スレッド リストをステップ実行する必要はありません。
サンプル アプリケーションについては、以下の点に注意してください。
アプリケーションで使用する方法は、識別データの競合がどの程度予測されるかによります。
スレッドが CBL_THREAD_LIST ルーチンを使用した場合:
そのため、以下のことを実行するべきです。
この制限は、CBL_THREAD_LIST_END 呼び出しによりステップ実行が終了すると、すぐに解除されます。