2011-01-04 9 views
3

Cwrite()をシリアル化して、データ損失なしでkスレッド間で共有されるソケットにバイトを書き込むことができますか?私は、この問題の解決策にはユーザー空間のロックが含まれていると思います。スケーラビリティについてはどうですか?前もって感謝します。posix C write()とスレッドセーフ

答えて

0

POSIXでは、send(2)でアトミック性の保証が指定されていないようですので、おそらくmutexを使用する必要があります。この種のシリアライゼーションでは、スケーラビリティが低下します。

0

ロック機構を使用する方法が考えられます。すべてのスレッドは、ソケットに何かを書き込む前にロックを待つ必要があり、ロックが完了するとロックを解除する必要があります。 すべてのスレッドがまったく同じ種類のメッセージを送信している場合、受信側はデータの読み取りに問題はありませんが、別のスレッドが可能な異なる情報で異なる種類のデータを送信できる場合は、各種類のデータに関連付けられており、スレッドIDも送信する方が良い(ただし、必要ではありませんが、小さな問題のデバッグに役立ちます)。

typedef struct my_socket_data_st 
{ 
int msg_id; 
#ifdef __debug_build__ 
    int thread_id; 
#endif 
size_t data_size_in_bytes; 
.... Followed by your data .... 
} my_socket_data_t 

スケーラビリティは、アプリケーションが実行されていることになるのハードウェアリソースを含む多くのものに依存します。

はあなたのような構造を有することができます。それはネットワークアプリケーションなので、ネットワーク帯域幅についても考える必要があります。ソケットを使ってデータを送受信する際のOSからの制限はありませんが(あなたのアプリケーションではこれを無視することはできますが)、sendを同期または非同期にすることについて考慮する必要があります。あなたの要件。また、ロックを取っているので、ロックの輻輳についても考慮する必要があります。ロックが他のスレッドに簡単に利用できない場合、パフォーマンスが大幅に低下します。

4

あなたのスレッドが応答を同期的に待つ必要があるかどうかによって、正しい答えが決まると思います。彼らがソケットに何らかのメッセージを書いてピアが応答するのを待たずに済んだら、最良の答えは、他のスレッドがメッセージを置くキューからメッセージを書くことに専念する単一のスレッドを持つことだと思います。こうすることで、ワーカースレッドはキューにメッセージを置くだけで、何か他のことを行うことができます。

もちろん、キューはミューテックスによって保護されていなければなりませんが、いずれかのスレッドがキューを操作している間はロックを保持する必要があります(かなり短い時間であることが保証されています)。すべてのスレッドにソケットを直接書き込ませるより明白な方法は、書き込み操作が完了するまで各スレッドがロックを保持することです。これは、書き込みがシステムコールであり、潜在的に長期間ブロックする可能性があるため、キューに項目を追加するよりもずっと長くなります。

あなたのスレッドがメッセージに応答する必要がある場合でも、それでも同じようなことをするにはお金がかかるかもしれません。あなたのソケットサービススレッドは、ブロックされないように読み書きのためにソケット上にselect()のような何かをしなければならないのでもっと複雑になります。また、メッセージを応答にマッチさせる方法とスレッドに通知する方法が必要になります彼らの反応が到着したとき。