FreeBASIC マニュアルのトップに戻る

FreeBASIC MutexCreate

目次→実行時ライブラリー参考→多重スレッド化サポートMUTEXCREATE←オリジナル・サイト

MUTEXCREATE 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

スレッドの実行を同期化させるために使われる、ミューテックス(Mutex:MUTual EXclusion:相互排他) を作成します。

構文:
declare function Mutexcreate ( ) as any ptr

用法:
result = Mutexcreate

戻り値:
作成されたミューテックスの any ptr ハンドル。失敗の場合は、ヌルポインタ (0)。

記述:
Mutexe(ミューテックス)とは、"Mutually Exclusive" (互いに排他的である)の短縮表記で、スレッド内の共有データを同期させる方法です。
複数のスレッドで使われるグローバル変数がある(または、単一スレッドで使われる局所静的変数でも、複数回呼ばれる)場合は、変数は、使われている間、ミューテックスで「ロック」する必要があります。
これにより、すべてのスレッド(主プログラムを実行する暗黙のメインスレッドを含む)は、そのミューテックスで、Mutexunlock でロックが解除されるまで、Mutexlock を使って停止します。

Mutexcreate は、ミューテックスを作成します。そして、ミューテックスを、ロックするか、錠を開けるか、破壊するとき、参照されるハンドルを返します。
Mutexcreate で作成されるミューテックスは、これ以上は必要なくなるか、あるいは、プログラムの終了前に、Mutexdestroy で破壊されなければなりません。

ミューテックは、以下の 3つを保証するロックです:
1. アトミック性(不可分性) - ミューテックスをロックすることは、原子(不可分)操作です。この意味は、あなたがミューテックスをロックしたなら、他のどんなスレッドも、同時にこのミューテックスをロックできないことを、オペレーティング・システム(または、スレッド化されたライブラリ)が、保証することです。
2. 単独性 - スレッドがミューテックスをロックしたなら、他のどのスレッドも、元のスレッドがロックを解除するまで、スレッドをロックできないことが、保証されます。
3. 非使用中の待機 - 2番目のスレッドによってロックされたスレッドを、1番目のスレッドがロックしようとすると、1番目のスレッドは、2番目のスレッドがロックを解放するまで、中断されます。このとき、どんな CPU リソースも消費しません。
2番目のスレッドがロックを解放すると、1番目のスレッドは、目覚めて、実行を続けます。こんどは、この1番目のスレッドがミューテックスをロックします。

例:
Threadcreate の例も参照して下さい。

'ミューテックスを使って、2つのスレッド間の相互排他の目に見える例:
'"user-defined thread" は、円上の点の座標を計算します。
'"main thread" は、点を打点します。
'
'Principle of mutual exclusion
'          Thread#A                XOR                  Thread#B
'.....                                         .....
'MutexLock(mut)                                MutexLock(mut)
'  Do_something#A_with_exclusion                 Do_something#B_with_exclusion
'MutexUnlock(mut)                              MutexUnlock(mut)
'.....                                         .....
'
'Behavior:
'- The first point must be pre-calculated.
'- Nothing prevents that a same calculated point could be plotted several times
'(depends on execution times of the loops between main thread and user thread).
'- Nothing prevents that a calculated point could be not plotted
'(same remark on the loop times).
'
'If you comment out the lines containing "MutexLock" and "MutexUnlock"
'(inside "user-defined thread" or/and "main thread"),
'there will be no longer mutual exclusion between computation of coordinates and plotting of points,
'and many points will not be plotted on circle (due to non coherent coordinates).

'-----------------------------------------------------------------------------------------------------

Type ThreadUDT                                   'Generic user thread UDT
    Dim handle As Any Ptr                        'Any Ptr handle to user thread
    Dim sync As Any Ptr                          'Any Ptr handle to mutex
    Dim quit As Byte                             'Boolean to end user thread
    Declare Static Sub Thread (ByVal As Any Ptr) 'Generic user thread procedure
    Dim procedure As Sub (ByVal As Any Ptr)      'Procedure(Any Ptr) to be executed by user thread
    Dim p As Any Ptr                             'Any Ptr to pass to procedure executed by user thread
    Const false As Byte = 0                      'Constante "false"
    Const true As Byte = Not false               'Constante "true"
End Type

Static Sub ThreadUDT.Thread (ByVal param As Any Ptr) 'Generic user thread procedure
    Dim tp As ThreadUDT Ptr = param                  'Casting to generic user thread UDT
    Do
        Static As Integer I
        MutexLock(tp->sync)                          'Mutex (Lock) for user thread
        tp->procedure(tp->p)                         'Procedure(Any Ptr) to be executed by user thread
        I += 1
        Locate 30, 38
        Print I;
        MutexUnlock(tp->sync)                        'Mutex (Unlock) for user thread
        Sleep 5, 1
    Loop Until tp->quit = tp->true                   'Test for ending user thread
End Sub

'-----------------------------------------------------------------------------------------------------

Type Point2D
    Dim x As Integer
    Dim y As Integer
End Type

Const x0 As Integer = 640 / 2
Const y0 As Integer = 480 / 2
Const r0 As Integer = 200
Const pi As Single = 4 * Atn(1)

Sub PointOnCircle (ByVal p As Any Ptr)
    Dim pp As Point2D Ptr = p
    Dim teta As Single = 2 * pi * Rnd
    pp->x = x0 + r0 * Cos(teta)
    Sleep 5, 1                         '無相関データが発生する可能性を高めます
    pp->y = y0 + r0 * Sin(teta)
End Sub


Screen 12
Locate 30, 2
Print "<any_key> : exit";
Locate 30, 27
Print "calculated:";
Locate 30, 54
Print "plotted:";

Dim Pptr As Point2D Ptr = New Point2D
PointOnCircle(Pptr)                   ' 円上で有効な最初の点を計算

Dim Tptr As ThreadUDT Ptr = New ThreadUDT
Tptr->sync = MutexCreate
Tptr->procedure = @PointOnCircle
Tptr->p = Pptr
Tptr->handle = ThreadCreate(@ThreadUDT.Thread, Tptr)

Do
    Static As Integer I
    Sleep 5, 1
    MutexLock(Tptr->sync)   'Mutex (Lock) for main thread
    PSet (Pptr->x, Pptr->y) 'Plotting one point
    I += 1
    Locate 30, 62
    Print I;
    MutexUnlock(Tptr->sync) 'Mutex (Unlock) for main thread
Loop Until Inkey <> ""
 
Tptr->quit = Tptr->true
ThreadWait(Tptr->handle)
MutexDestroy(Tptr->sync)
Delete Tptr
Delete Pptr

Sleep


同様の Condcreate の例も参照下さい。

方言差:

プラットホーム差:

QBからの違い:

参照:
多重スレッド化サポート に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2020-11-30 03:51:19
日本語翻訳:WATANABE Makoto、原文著作者:JofersToonski

ホームページのトップに戻る

表示-非営利-継承