スレッドを、アプリケーション内で作成された他のスレッドと区別すると役立つことがあります。たとえば 4 つのスレッドをもつアプリケーションで、2 つのスレッドが作成側と使用する側の関係にある場合には、お互いのスレッドのスレッド ハンドルを知ることは、これら連動する 2 つのスレッドにとって役に立ちます。これらのハンドルを取得した後は、CBL_THREAD_SUSPEND と CBL_THREAD_RESUME の呼び出しのみを使用してすべての同期を取ることができます。アプリケーション内の各スレッドが、その機能に関連する名前を作成し、その名前をスレッド ハンドルに関連付けると、連動するスレッドはスレッド名のリストを検索し、お互いのハンドルを検出できます。
グローバルにアクセス可能なデータを各スレッドとそのハンドルに関連付けると、終了フラグを保持し、CBL_THREAD_KILL を使用する可能性を未然に防ぐことができます。アプリケーションの各スレッドは、終了要求を確認するためにその終了フラグをポーリングできます。終了するスレッドは、正常に終了する前に、ロックが保持されていないことと、アクションの同期を取る必要がないことを確認します。
スレッドのグローバルにアクセス可能なデータは、スレッド内で CBL_THREAD_IDDATA_ALLOC ルーチンを実行するとスレッド ハンドルに関連付けられます。スレッド ハンドルが既に認識されている場合は、CBL_THREAD_IDDATA_GET ルーチンを使用してこのデータを取得します。一方、スレッド ハンドルが認識されていない場合は、CBL_THREAD_LIST_n ルーチンを使用してこのデータを取得します。
例 - グローバルにアクセス可能なデータとスレッド ハンドルの関連付け
次の例では、スレッド内で CBL_THREAD_IDDATA_ALLOC を呼び出して、グローバルにアクセス可能なデータをスレッド ハンドルに関連付ける方法を示します。スレッド ハンドルがすでに認識されている場合は、CBL_THREAD_IDDATA_GET を呼び出してデータを取得します。スレッド ハンドルが認識されていない場合は、CBL_THREAD_LIST_n ルーチンを使用してこのデータを取得します。
*************** MAINPROG.CBL ************************
identification division.
program-id. mainprog.
Data Division.
Local-Storage Section.
01 ret-wait 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
start 'SUBPROG ' identified by sub-handle
* 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
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 1 to iddata-term
* Wait until the child ends
wait for sub-handle *> clear up thread's resources
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_n ルーチンを使用した場合:
そのため、以下のことを実行するべきです。
この制限は、CBL_THREAD_LIST_END 呼び出しによりリスト ステップ実行が終了すると、すぐに解除されます。