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

FreeBASIC ThreadCreate

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

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

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

ユーザが定義した手続きを、別々の実行スレッドで始めます。

構文:
Declare Function Threadcreate _
( _
ByVal procptr As Sub ( ByVal userdata As Any Ptr ), _
ByVal param As Any Ptr = 0, _
ByVal stack_size As Integer = 0 _

) As Any Ptr

用法:
result = Threadcreate ( procptr [, [ param ] [, stack_size ] ] )

パラメタ:
procptr
スレッドとして動作することを意図した Sub へのポインタ。
(サブへのポインタを取得するには、Operator ProcPtr (手続きポインタと vtable 索引) を参照)
サブは、procptrと互換性を持つために、以下の署名(同じパラメータ、同じ呼び出し規約)が必要です:
Declare Sub myThread ( ByVal userdata As Any Ptr )

userdata
SubAny Ptr パラメータは、スレッドとして働くつもりでした。
FreeBASIC は、このパラメータが存在することを期待します。これを省略してはいけません!

param
Any Ptr 引数は、その userdata パラメーターを通して、 procptr によって、ポイントされる、スレッド Sub に渡されます。
例えば、これは、構造へのポインター、あるいはスレッド sub が作動する様々な情報を含んでいる配列でありえます。
param が与えられなければ、代わりに、0 (ゼロ) が、スレッド sub の userdata パラメーターに渡されます。

stack_size
このスレッドのスタックのために用意する、バイト数で、任意です。

戻り値:
ThreadCreate は、作成されたスレッドへの any ptr ハンドルを返します。失敗の場合は、ヌルポインタ (0) を返します。

記述:
procptr によって指される sub は、スレッドとして始まります。
この userdata パラメータで、param の内容を渡されます。指定されなければ、 0 (zero) を渡されます。

スレッドとして起動した sub は、プログラムの主要部分と並行して実行されます。
OS は、別のプロセッサがあればそれに割り当てたり、1つのプロセッサ上で実行スレッドを交互に切替えることで、これを実現します。
異なるスレッドの実行順序については保証されておらず、複数生成されたスレッドが、実際に実行を開始する順序について仮定できません。
ThreadCreate からスレッドの実際の実行開始までの時間は可変であり、コンテキストに応じて長くも短くもなります (したがって、ThreadCreate 命令文に続く一部の命令文は、スレッドが実際に起動される前に実行される可能性があります)。
最速で起動する場合には、ThreadCreate が戻る前でもスレッド本体が実行開始することがあります。

実行中の各スレッドは、実行中のすべてのスレッド間で一意のハンドルによって識別できます。ThreadSelf を参照してください。

閉じる前に、プログラムは、ThreadWait を使って、開始しているすべてのスレッドの終了を待つべきです。
あるいは、スレッドの実行終了を、安全に待つ必要がない場合、ThreadDetach を使うことができます。
しかし、もし、スレッドがまだ動いているのに、プログラムを終了させると、そのスレッドはシステムによって異常終了するでしょう。
作成されたすべてのスレッドについて、プログラムは、ThreadWaitThreadDetach のいずれかを呼んで、スレッド・ハンドルに関連したシステム・リソースが、リリースされることを保証すべきです。
そうしないと、メモリかシステム・リソースが、漏れます。

スレッドの性質により、実行順序を想定することはできません。
スレッドおよびプログラムの主要部分を含む、複数のスレッドの間のデータを交換するために、ミューテックを使わなければなりません。
これらの相互排他ロックは、重大な仕事の間、単一のスレッドによって「専有」することができ、その結果、他のスレッドの実行を待たせることができます。
Mutexcreate, Mutexlock, Mutexunlock, Mutexdestroy を参照下さい。

stack_size を使うと、スレッドのスタック・サイズを、システムのデフォルトから変更できます。
これは、プログラムが、大きいスタックを必要とするとき、役に立ちます。たとえば、たくさんの手順再帰のためや、スタック上で、巨大な文字列/配列を割り当てるときです。
いくつかのシステム(Linux)では、より多くのスペースが必要なら、スタックは、自動的に stack_size を超えて増大します;
他(Win32)では、stack_size は、固定の最大許容量です。
スタックが拡大できないシステムでは、予約されたサイズより多くのスタックを使おうとするとき、ふるまいは未定義です。

組み込みマクロ __FB_MT__ は、ThreadCreate の使用時点以降のみ自動的に設定されます。

注意:
- userdata パラメーターは myThread サブの本体では使わなくても構いませんが、ヘッダーでは Any Ptr パラメーターとして宣言することは常に必須です。
この場合、ThreadCreate を呼び出すときに、対応する param パラメーターを省略できます。あるいは、不要な引数を渡すこともできます(「0」が一般的に使われるのは、この値がどのようなポインタとも直接互換性があるからです)。 2番目と 3番目の例を参照してください。
- myThread にデータを渡す必要がある場合は、Any Ptr param を使ってデータを参照できます。通常、ThreadCreate にデータを渡す前に Any Ptr への型変換(暗黙的または明示的)が必要となり、myThread の本体でデータを使う前に Any Ptr からの逆型変換が必要となります。 1 つ目の例を参照してください。

例:
'' ミューテックスを使ってスレッド同期
'' 「MutexLock」と「MutexUnlock」を含む行コメントアウトすると、
'' スレッドは同期しません。
'' そして、データの一部は不適当な場所に表示されるかもしれません。

Const MAX_THREADS = 10

Dim Shared As Any Ptr ttylock

'' テレタイプは、与えられた位置で画面を横切ってテキストを開きます。
Sub teletype( ByRef text As String, ByVal x As Long, ByVal y As Long )
    ''
    '' この MutexLock は、スレッドを互いを待たせて、同時させます。
    '' それで、一つずつ続けることができて、出力を表示します。
    '' さもなければ、その Locates は干渉します。カーソルは一つしかないからです。
    ''
    '' どのスレッドがここに到着するか、
    '' どれが、他のスレッドを待たせているロックを最初に得るか、
    '' 順番を予測することは、不可能です。
    ''
    MutexLock ttylock

    For i As Integer = 0 To (Len(text) - 1)
        Locate x, y + i
        Print Chr(text[i])
        Sleep 25, 1
    Next

    '' MutexUnlock はロックを出して、他のスレッドにそれを取得させます。
    MutexUnlock ttylock
End Sub

Sub thread( ByVal userdata As Any Ptr )
    Dim As Integer id = CInt(userdata)
    teletype "Thread (" & id & ").........", 1 + id, 1
End Sub

    '' ミューテックスを作成して、スレッドを同期します
    ttylock = MutexCreate()

    '' 子スレッドを生成
    Dim As Any Ptr handles(0 To MAX_THREADS-1)
    For i As Integer = 0 To MAX_THREADS-1
        handles(i) = ThreadCreate(@thread, CPtr(Any Ptr, i))
        If handles(i) = 0 Then
            Print "Error creating thread:"; i
            Exit For
        End If
    Next

    '' これは、主スレッドです。今、すべての子スレッドが終わるのを待ちます
    For i As Integer = 0 To MAX_THREADS-1
        If handles(i) <> 0 Then
            ThreadWait(handles(i))
        End If
    Next

    '' Clean up when finished
    MutexDestroy(ttylock)
    Sleep



Sub print_dots(ByRef char As String)
    For i As Integer = 0 To 29
        Print char;
        Sleep CInt(Rnd() * 100), 1
    Next
End Sub

Sub mythread(param As Any Ptr)
    '' Work (other thread)
    print_dots("*")
End Sub

    Randomize(Timer())

    Print " main thread: ."
    Print "other thread: *"

    '' Launch another thread
    Dim As Any Ptr thread = ThreadCreate(@mythread, 0)

    '' Work (main thread)
    print_dots(".")

    '' Wait until other thread has finished, if needed
    ThreadWait(thread)
    Print
    Sleep



'' Threaded consumer/producer example using mutexes

Dim Shared As Any Ptr produced, consumed

Sub consumer( ByVal param As Any Ptr )
    For i As Integer = 0 To 9
        MutexLock produced
        Print ", consumer gets:", i
        Sleep 500, 1
        MutexUnlock consumed
    Next
End Sub

Sub producer( ByVal param As Any Ptr )
    For i As Integer = 0 To 9
        Print "Producer puts:", i;
        Sleep 500, 1
        MutexUnlock produced
        MutexLock consumed
    Next i
End Sub

    Dim As Any Ptr consumer_id, producer_id

    produced = MutexCreate
    consumed = MutexCreate
    If( ( produced = 0 ) Or ( consumed = 0 ) ) Then
        Print "Error creating mutexes! Exiting..."
        End 1
    End If

    MutexLock produced
    MutexLock consumed
    consumer_id = ThreadCreate(@consumer)
    producer_id = ThreadCreate(@producer)
    If( ( producer_id = 0 ) Or ( consumer_id = 0 ) ) Then
        Print "Error creating threads! Exiting..."
        End 1
    End If

    ThreadWait consumer_id
    ThreadWait producer_id

    MutexDestroy consumed
    MutexDestroy produced

    Sleep


方言差:

プラットホーム差:

QBからの違い:

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

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

表示-非営利-継承