- PR -

ブロッキング・ノンブロッキング関数について

1
投稿者投稿内容
freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2006-12-08 11:41
こんにちは。
すみません、再度疑問点がありますので、投稿させていただきます。

以前、send,sendto,recv等の関数はブロッキング関数ですが、ブロッキングとは・・・甕星さんのご指摘として、

送信時の「処理が完了するまで」とは「送信バッファに書き込むまで」を指します。したがって送信バッファへの書き込みが完了すれば(データが送信される前に)戻ってきます。送信バッファに空きがなければ戻ってきません。

とお答えいただきました。

と言うことは・・・
有線環境でブロッキング関数を用いると下位レイヤの帯域が大きいので、すぐにバッファに空きができ返ってくるが、無線環境では帯域が有線に比べて小さいので、いくらアプリケーションでパケットを早く送出しようとしても、バッファに空きがないため返ってくるのに時間がかかるもしくは、アプリケーションが停止してしまう。

とのことでしょうか?

有線と無線でブロッキング関数を用いてソケット通信してみたところ、パケットの送出時間が有線<無線であったため、疑問に思いました。

これらから、バッファに格納されるまで返ってこないブロッキング関数は、ノンブロッキング関数に比べて、信頼性?という面で優れているのでしょうか?

よろしくお願い致します。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-12-08 12:13
引用:

freebirdさんの書き込み (2006-12-08 11:41) より:
以前、send,sendto,recv等の関数はブロッキング関数ですが、ブロッキングとは・・・甕星さんのご指摘として、

送信時の「処理が完了するまで」とは「送信バッファに書き込むまで」を指します。したがって送信バッファへの書き込みが完了すれば(データが送信される前に)戻ってきます。送信バッファに空きがなければ戻ってきません。



OSが限定されていないので一般論ですが、
send()/recv()等はデフォルトでブロックします。
非ブロッキングモードに変更すれば変わります。

ブロッキングモードと非ブロッキングモードの最大の違いは、
呼び出した時点ですぐに処理を完了できない場合に
待機するかしないかです。

引用:

と言うことは・・・
有線環境でブロッキング関数を用いると下位レイヤの帯域が大きいので、すぐにバッファに空きができ返ってくるが、無線環境では帯域が有線に比べて小さいので、いくらアプリケーションでパケットを早く送出しようとしても、バッファに空きがないため返ってくるのに時間がかかるもしくは、アプリケーションが停止してしまう。



有線でも無線でも、光ファイバでも、電話回線でも変わりません。
速い回線でもそれ以上の帯域のデータを流せばブロックします。

引用:

これらから、バッファに格納されるまで返ってこないブロッキング関数は、ノンブロッキング関数に比べて、信頼性?という面で優れているのでしょうか?



信頼性では変わりません。バッファに入ったからといって、
それが最終的に通信相手に届く保証にはなりませんし。

#TCPではsend()の成功は相手に届いた保証にはなりません。
#OSが送信を受け付けた、という意味の成功に過ぎません。

ブロッキングモードでは、操作を完了できない場合に無条件で待機しますが、
非ブロッキングモードでは、完了できなかったとして処理が返されるので、
タイムアウトを設けて待機したり、他の処理をすることが可能になります。

#setsockopt()でタイムアウト設定も可能ですが、それは別の話ということで。
freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2006-12-08 13:07
返信ありがとうございます。
実行環境は、VC++.NETでC言語にてコンソールプログラミングを行なっています。

引用:

あしゅさんの書き込み (2006-12-08 12:13) より:
ブロッキングモードと非ブロッキングモードの最大の違いは、
呼び出した時点ですぐに処理を完了できない場合に
待機するかしないかです。

有線でも無線でも、光ファイバでも、電話回線でも変わりません。
速い回線でもそれ以上の帯域のデータを流せばブロックします。



たとえば、sendtoやsendまたはrecvfromやrecv等のブロッキング関数では、バッファに格納されれば、送信バイト数を返し次の実行を行なうということでしょうか?

有線と無線環境で、同じプログラムを実行した際、すべてのパケットを送出し終える時間が無線>有線であるため、なぜか?と疑問に思ったからです。

そこで・・・ブロッキング関数を用いているからではないか?と考えた次第です。
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2006-12-08 19:54
ブロックしたらタイムアウト処理が出来ないかというとそんなことはなくて。
結局は「ブロックするのとしないのとどちらのほうがプログラムが書きやすいか、
パフォーマンスが出るか」という点で決めることになるわけです。
# パフォーマンスが問題になるのは同時に複数のソケットを扱う場合の話。
# ブロックする場合、マルチスレッドで書くことになるので。

引用:

freebirdさんの書き込み (2006-12-08 13:07) より:
有線と無線環境で、同じプログラムを実行した際、すべてのパケットを送出し終える時間が無線>有線であるため、なぜか?と疑問に思ったからです。


仮に、理想的なテスト用ネットワーク環境が用意できたとして。
時間が違ってくる要素としては、OSとか、OSのネットワーク設定とか、
ネットワークインタフェースのハードウェアとか、デバイスドライバとか、
いろいろありますが。
freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2006-12-11 02:42
返信ありがとうございます。
引用:

ぽんすさんの書き込み (2006-12-08 19:54) より:
ブロックしたらタイムアウト処理が出来ないかというとそんなことはなくて。
結局は「ブロックするのとしないのとどちらのほうがプログラムが書きやすいか、
パフォーマンスが出るか」という点で決めることになるわけです。
# パフォーマンスが問題になるのは同時に複数のソケットを扱う場合の話。
# ブロックする場合、マルチスレッドで書くことになるので。



私は、受信スレッドおよび送信スレッドを生成しマルチスレッド処理を行っています。ブロックする場合、マルチスレッドで書くとはどういうことでしょうか?
ブロッキング関数を用いる場合は、マルチスレッドで記述するということでしょうか?

また、1スレッドにsendとrecv関数が存在する記述方法は誤りでしょうか?
1スレッドには一つのブロッキング関数のみにしたほうがよい?と聞いたことがありましたので・・・

よろしくお願い致します。
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2006-12-11 08:10
引用:

freebirdさんの書き込み (2006-12-11 02:42) より:
ブロックする場合、マルチスレッドで書くとはどういうことでしょうか?


ブロックしたらその間ほかのソケットで送信/受信できないから、
というだけの単純な話です。

例えば、同時に複数の相手と通信するプログラムをどうやって書くか、とか。
1

スキルアップ/キャリアアップ(JOB@IT)