質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

4回答

5203閲覧

C言語で処理のスケジューリング

退会済みユーザー

退会済みユーザー

総合スコア0

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2015/12/25 07:45

C言語のプログラムを書いています.
現在ネットワークのソケット通信部分をマルチスレッドの形にしてプログラムを書いているのですがサーバプログラム側の性能(実装方法?)の問題で処理の待ち受けが発生してしまっています.
そのためマルチスレッディングで同時アクセスすることをやめ, スケジューリングを行い, 一定期間で処理を連続して行おうということを考えました.
ただし処理時間の制約が非常に強く, 例えばマルチスレッディングをやめてシーケンシャルにアクセス...といった実装はできないです.

どのような解決方法があるでしょうか?
現在はこちらから送るリクエスト数の合計は5000くらいを想定していて, 同時にスレッドを作成し, 通信していますが
だいたいサーバ側で処理の待ち受けが発生するのは同時アクセス数150あたりからのようです.
考えたのは150アクセスごとに分け, スケジューリングをして適切な感覚で送信することなのですが実装方法がいまいちわかりません.
よろしくお願いいたします.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kozuchi

2015/12/25 08:42

以下の点について追記したほうがよい回答をもらえると思います。 ・プロトコルは何を使っていますか? ・開発対象にサーバは含まれますか(サーバ側での対応は考慮に含めていいですか?) ・サーバ(アクセス対象)は一つですか(Webサーバであれば複数サイトですか、一つのサイトですか?) ・サーバ側はどのような構成を想定していますか?(負荷分散などはどうしている前提ですか?) ・何のためにマルチスレッド化するのですか?(マルチスレッド化で期待する効果はなんですか?) ※また、C言語とマルチスレッドを使ってらっしゃいますが、 どちらかというとネットワークプログラミングの問題ですので、 タグには「ネットワーク」と、 使用可能なタグに使っているプロトコルタグにあれば そのプロトコルのタグ(「HTTP」「FTP」など)を指定することをお勧めします。
guest

回答4

0

あらかじめスレッドを作成しておいて,親スレッドはリクエストが来たら空いている子スレッドに処理を投げるだけ,子スレッドは受け取ったリクエストをさばく,という実装になっているのでしょうか?

スレッド数を増やせば,空いている子スレッドが無いために親がリクエストを保留するという待ちは減らせるかもしれませんが,同時に実行できるスレッド数にはCPUに依存する限界がありますから,子スレッドがリクエストをさばくためにCPUのスケジューリング待ちをする時間はどうしても存在します.
OSの機能を使って作ったスレッドであればOSのスケジューラに依存しますし,ユーザレベルのスレッド機能を使って作ったスレッドであればそのライブラリか何かのスケジューラに依存します.
一般ユーザレベルスレッドの方が高速に切り替えられると言われているので,互換性は犠牲になりますが,スループットを向上させるためには良いかもしれません.

逆に,子スレッドの空きは十分にあるのに,親スレッドのリクエストのさばき方が悪いために遅くなる場合もあります.
どのような関数でリクエストの到来を待っているのかによって,同時接続数の上限も変動する可能性があります.(Linuxであればselect,poll,epollなどたくさんあります)

まずは,どこがサーバプログラムのボトルネックになっているのかの調査が必要だと思います.
また単一のサーバプログラムで処理をすべて行うためには,上述のような限界もありますので,ロードバランサの導入も検討してみてください.
(「150アクセスごとに分け, スケジューリング」というのはロードバランサのことでしょうか?)

投稿2015/12/25 08:33

編集2015/12/25 08:35
KenTerada

総合スコア751

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

セマフォを使って同時リクエスト数を100くらいに制限しては如何でしょうか?
セマフォの内カウンティングセマフォと呼ばれるものが使えると思います。

Windowsならこの辺が参考になると思います。
その他のOSについては私は分かりませんが、linuxもありそうです。

投稿2015/12/25 08:28

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「処理時間の制約が非常に強く・・・」とありますので、例えばハードウェア割り込み処理(短時間で処理を完了してCPUを開放する必要がある)の中で、サーバーへのデータ送信を実行しようとしているが、サーバー側のレスポンスが遅くて完了待ちが発生してしまう、というような状況だと仮定します。

この場合、定番のデザインパターンとして、「送信キュー」という仕組みを作ります。割り込み処理の中ではリクエストメッセージを作成してそれをキューに入れ、ただちに処理を完了させるようにします。そうしておいて、このキューからリクエストメッセージを取り出してサーバーに送信する処理を別スレッドで走らせます。もしサーバーへ送るリクエストの順番を維持したい場合はスレッド数を増やす、リクエストの順番に意味がないのであれば、キューとスレッドをセットで増やすなどの方法で、パフォーマンスを最適化することができます。

「キュー」とは何かということについては、「キューとスタック」などで検索すると多数ヒットします。簡単に言うと、同時多発的に発生するデータを一列に整列させ、FIFO(First in First out/先に列にならんだものを先に)処理するための仕組みです。単純なキューは、構造体やクラスインスタンスの実体かポインタの配列として実装されます。ただし配列要素数が数千や数万の単位で可変長になる場合には、単方向/双方向のオブジェクト参照リストとして実装するほうがパフォーマンス的に有利にできると思います。

クライアント/サーバーシステムで「送信キュー」や(今回は不要ですが)「受信キュー」などの仕組みを使うパターンについては、「メッセージキュー」や「疎結合分散システム」などで検索するとより詳しい情報を得ることができると思います。

ご参考になれば。

投稿2015/12/25 08:22

tkanda

総合スコア2425

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

一般的な話になってしまいますが、送受信処理をうまく回すためには、送受信スレッドは1つずつにするのが普通です。つまり、送受信の交通整理を専門で行うスレッドを用意するわけです。送信スレッドは送信に専念し、受信スレッドは受信に専念するわけです。
ハンドシェーク要求を持っているスレッドはそれとは別に(1つないし複数)作成しておき、各ハンドシェークスレッドは送信スレッドにキューなどを使って送信要求を出します。送信スレッドはキューを監視しておいて、データが有ればサーバーにデータを送ります。
受信スレッドは、受信データがあれば各ハンドシェークスレッドに受信データを返します。ただ、ハンドシェークスレッドが複数ある場合は、受信データからどのハンドシェークスレッドに返したらいいのか区別できるようにしておかなければいけません。その辺はデータの内容によって分けることになるのでハンドシェークスレッドの別け方をどうするかということになります。
こうすれば、時間待ち(監視)は各ハンドシェークスレッド個々で行えばいいことになります。各ハンドシェイクスレッドの送信周期も各スレッド毎に制御します。

後は待受が発生したことをどう認識するかですが、サーバー側の話なので基本的には難しいと思います。サーバーに送信するアプリが1つしか無いのであれば送受信数で判断つきますが、サーバーには複数のアプリから要求が来るでしょうから、それを各クライアントが判断するのは基本的には難しく、レスポンス時間で判断するするしか無いように思います。

投稿2016/01/05 09:14

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問