1

こんにちは、私は、マルチ セマフォで POSIX スレッドを使用することに関する割り当てに取り組んでいます。割り当ての簡単な説明は次のとおりです。4 つのさまざまなデータ パケット (char/video/audio/image) があり、それぞれが異なるスレッドによって運ばれ、共有バッファーもあります。システムで動作できる最大スレッド数は、ユーザーが入力として維持します。例えば; ユーザーが 10 を入力すると、最大 10 のスレッドが作成され、特定の時間内にバッファを介してデータ パケットが送信されます。今、私にとって紛らわしい部分は、このバッファには限られたパケットを即座に含めることができるということです。(たとえば、最大 10 個の char パケットと 20 個のビデオ パケットなどを含めることができます) そのため、データ タイプごとに異なるセマフォを用意する必要があります。問題は、非常に単純なセマフォでバッファサイズを制御する方法を知っていますが、パケットのセマフォを使用するという正しい考えを設定することはできません。私はいくつかの異なる方法を試しましたが、常にデッドロックエラーに直面していました。これが私のプログラムをより明確に理解するための私の擬似コードです。

define struct packege
define semaphore list

main

initialize variables and semaphores

while threadCounter is less than MaxThreadNumber

switch(random)
case 0: create a character package
    create a thread to insert the package in buffer
case 1: create a video package
    create a thread to insert the package in buffer
case 2: create an image package
    create a thread to insert the package in buffer
case 3: create an audio package
    create a thread to insert the package in buffer

increment  threadCounter by one
end of while

create only one thread which will make the dequeue operation
end of main

producer function

for i->0 to size_of_package
    sem_wait(empty_buffer) // decrement empty_buffer semaphore by size of package

    lock_mutex
        insert item into queueu
        decrement counter of the buffer by size of package
    unlock_mutex

for i->0 to size_of_package
    sem_post(full_buffer) // increment full_buffer semaphore by size of package

end of producer function

consumer function

while TRUE // Loops forever

    lock_mutex

        if queue is not empty
            dequeue

        increment counter of the buffer size of package

    unlock_mutex

for i->0 to size_of_package // The reason why i making the sem_wait operation here is i cant make the dequeue in outer region of mutex.
    sem_wait(full_buffer)
for i->0 to size_of_package
    sem_post(empty_buffer)
end of consumer function

この実装プログラムでは正しく動作します。しかし、パッケージのスレッドに属するセマフォを適切に使用できませんでした。私はすべての推奨事項を聞くことができ、すべての回答に感謝します。

4

2 に答える 2

1

これは、セマフォの使用方法ではありません。バッファの制御変数/構造は、バッファに含まれるメッセージの数とタイプをカウントする必要があります。ミューテックスは、異なるスレッドによる同時アクセスからバッファーとその制御変数/構造を保護します。セマフォを使用する場合は、バッファの状態をコンシューマに通知するだけで、パケットのサイズとは関係ありません。確かに、パケットのサイズによって増分されることはありません。

セマフォの代わりにpthread条件変数を使用することをお勧めします。これらは、スレッド間のレースフリーシグナリングを保証するためにpthreadミューテックスと関連して使用されます。プロデューサーループはこれを行います:

  • ミューテックスをロックし、
  • 新しいパケットを追加するためにバッファなどを変更し、
  • 条件変数を通知し、
  • ミューテックスのロックを解除します。

コンシューマーループはこれを行います:

  • ミューテックスをロックし、
  • バッファリングされたすべてのデータを処理し、
  • 条件変数を待ちます。

pthread_cond_init、、pthread_cond_signalおよびを読んでくださいpthread_cond_wait

于 2012-10-29T04:00:30.923 に答える
1

これは割り当てなので、おそらく実際のパケット データを読み書きする必要はなく、それらの処理をシミュレートするだけです。

その場合、問題は、プロデューサー スレッドがバッファーに書き込むことができるパケットの制限に達したときにプロデューサー スレッドを効果的にブロックする方法に要約されます。現時点では、セマフォを使用して、バッファに書き込まれたパケットの個々の要素を数えています。

バッファへの書き込みがアトミックであり、パケット要素ではなくパケットをカウントしたいだけだと想像してください。プロデューサがパケットを書き込むたびに、適切なセマフォを使用してそれをコンシューマに通知する必要があり、コンシューマがパケットを読み取るたびに、適切なプロデューサに通知する必要があります。

他のいくつかの点を強調しましょう。

  • セマフォの重要な特性は、値がゼロになるとブロックされることです。たとえば、初期値が 10 の場合、10 回連続で sem_get を実行すると、11 回目がブロックされます。
  • 4 種類のパケットがあり、それぞれバッファーに書き込むことができる数のしきい値が異なります。

前述したように、プロデューサーはパケットを書き込んだことを通知する必要がありますが、しきい値に達したら停止する必要もあります。これを実現するには、新しいパケットを送信するたびにセマフォを取得するようにしsem_getます。そして、消費者がsem_postパケットを読み取るたびに、単一のセマフォ バージョンで行ったことの逆を実行します。ただし、プロデューサをしきい値で停止させたいので、セマフォを の容量で初期化しますN - 1。N はしきい値です。バッファに書き込んだ後、新しいパケットが利用可能であることを通知する必要があることに注意してください。そうしないと、消費者がバッファをブロックする可能性があります。

producer<type> function

  write_packet()  // put the packet in the buffer
  sem_wait(type)    // signal a new packet is available 
  // (if there's not enough space for another packet, the producer will block here) 

end producer<type> function

consumer function

  while TRUE // Loops forever

      switch packet_available() // look if there's a new packet available
       case video:
         read_packet<video>()
         sem_post(video)
       (...)
       default: // no packet available, just wait a little
          sleep()
      end if
  end while

packet_readおそらくミューテックスを使用してバッファへのアクセスを制限しpacket_writeます。packet_available

于 2012-10-29T11:36:33.097 に答える