6

2.6.24.3 カーネルを使用して、組み込み Linux プロジェクトのユーザー空間アプリに取り組んでいます。私のアプリは、非同期 IO 操作が完了するまでそれぞれがスリープする 2 つの pthread を作成することにより、2 つのファイル ノード間でデータを渡します。

完了ハンドラーは、保留中の転送の数を追跡し、1 つのスレッドが追加し、もう 1 つのスレッドが削除するいくつかのリンクされたリストを維持する必要があります。

// sleep here until events arrive or time out expires
for(;;) {
    no_of_events = io_getevents(ctx, 1, num_events, events, &timeout);
    // Process each aio event that has completed or thrown an error
    for (i=0; i<no_of_events; i++) {
        // Get pointer to completion handler
        io_complete = (io_callback_t) events[i].data;
        // Get pointer to data object
        iocb = (struct iocb *) events[i].obj;
        // Call completion handler and pass it the data object
        io_complete(ctx, iocb, events[i].res, events[i].res2);
    }
}

私の質問はこれです...

ミューテックス/スピンロックルートを下るのではなく、完了ハンドラーを実行している間、現在アクティブなスレッドが譲歩するのを防ぐ簡単な方法はありますか?

または、ミューテックス/スピンロックが保持されているときに pthread を生成しないように Linux を構成できることに失敗しましたか?

4

3 に答える 3

6

システム コールを使用してsched_setscheduler()、スレッドのスケジューリング ポリシーを一時的に に設定してからSCHED_FIFO、再度設定することができます。sched_setscheduler()マニュアルページから:

プロセスは、I/O 要求によってブロックされるか、より優先度のSCHED_FIFO高いプロセスによって横取りされるか、または を呼び出すまで実行されますsched_yield(2)

(このコンテキストでは、「プロセス」は実際には「スレッド」を意味します)。

ただし、これは非常に疑わしい要件です。あなたが解決したい問題は何ですか?完了ハンドラーのリンクされたリストを同時アクセスから保護しようとしているだけの場合は、通常のミューテックスが適しています。完了スレッドにミューテックスをロックさせ、リスト項目を削除し、ミューテックスをロック解除してから、完了ハンドラーを呼び出します。

于 2010-05-19T13:26:58.923 に答える
1

ここで競合状態を防ぐためにミューテックス/ロックを使用したいと思うでしょう。ミューテックスは決してブードゥー教の魔法ではなく、システム間で移植する必要がある任意のシステム固有の機能を使用するよりも、コードを単純にすることさえできます。ただし、後者が問題であるかどうかはわかりません。

于 2010-05-19T15:56:19.033 に答える
1

間違った理由で、ここで Linux スケジューラの裏をかこうとしていると思います。

正しい解決策は、ミューテックスを使用して、完了ハンドラーが並行して実行されないようにすることです。スケジューラにその仕事をさせてください。

于 2010-05-19T16:04:10.093 に答える