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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

2回答

2833閲覧

双方向リストの排他制御

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2016/02/15 20:59

双方向リストについて、要素削除の際に排他制御をして処理の生合成を取ろうとしています。
しかし、双方向リストはC言語で実装しましたので、わかるのは先頭ポインタの指定アドレスのみです。

そこで疑問なのですが、書き換え処理の際に前後の要素にも値の書き換えを実行しなくてはいけません。
よってこの関数を実装したのち,クリティカルな処理のみをロックして実行すればいいのでしょうか?
またシグナルを実行しているのですが、その結果によってリストをいじる関数が呼ばれる可能性があります。
よってそのシグナルを一時的にブロックすることもできるのでしょうか?

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

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

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

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

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

cateye

2016/02/15 21:48

排他制御については環境依存な部分があります。環境(OS、コンパイラなど)を追記してください。
guest

回答2

0

ベストアンサー

まず、リストの使い方ですが用途は何でしょうか?
スタック的な使い方でしょうか?あるいはキューのような使い方でしょうか?
いずれにしても、処理内容を箇条書きでもいいから書き出して、どこを排他制御にする必要があるか考えて見ましょう。(たとえば挿入する部分、取り出す部分とかですね)
その上で、排他制御の無い処理を実装してみましょう。
テスト(データはちゃんと入っているか?、リンクアドレスはちゃんと設定されているかなど)をして問題がなくなったら、初めて排他の処理を入れてテストをした方がいいでしょう。
---本来の処理と排他を同時に実装するとデバッグで死にますorz---

あと、ほかの方も書かれていますがなぜシグナルがいるのでしょう? 周期で見たいならスレッドを起こせばいいだけだと思いますが?

投稿2016/02/16 09:05

cateye

総合スコア6851

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

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

0

こんにちは。

まず、「処理の生合成を取る」ってどのような意味でしょうか?
排他制御はスレッド間で同じリソースへの同時アクセスを制限するのに使われることが多いので、スレッド間の排他制御として回答します。もし、異なりましたら、「処理の生合成を取る」の意味を一般的な(ググったら出てくる程度に)用語にてご説明頂けると幸いです。

排他制御は、リソースをアクセスしている最中に他のスレッドが割り込むとまずいところを保護します。
例えば、ある変数の値が0なら++1して何かするような時、下記のようなコードを書くと思います。

C++

1if (!foo) 2{ 3 ++foo; 4 do_something(); 5}

この時、if (!foo)の直後に他のスレッドが割り込んで同じ処理をすると、片方のスレッドは++foo;とdo_something();してほしくないに、両方が実行してしまいます。
これを防ぐために、if (!foo) {++foo;の処理中に他のスレッドが割り込めないように排他制御します。

リストの場合はこの範囲がかなり広いです。リスト探索中に要素の追加/削除が行われると削除された要素をアクセスしたり、追加中でまだ設定されていないポインタを追跡したりと悲惨ですね。ですので、リストをアクセスする処理全体を排他制御する必要があります。(ピンポイントで排他制御しても、屋根に登ったあとから、ハシゴを外される状態になってしまいます。)

排他制御している部分は当たり前ですが、並列処理できないので、折角マルチスレッドで性能を確保しようとしていることが無駄になりかねません。ですので、排他制御は最低限で済むよう工夫することが重要です。
そもそもスレッドは使わないのが一番なのです。それではどうしても性能不足する場合に、最低限どの部分を排他制御する必要があるのかよく見極め、その排他制御期間を許容してもマルチ・スレッド化した方が性能を改善できる目処がある時に初めて検討します。

ですので、まずはtoma_kazusaさんのアプリをマルチ・スレッド化する必要性を検討されることをお薦めします。

またシグナルを実行しているのですが、その結果によってリストをいじる関数が呼ばれる可能性があります。よってそのシグナルを一時的にブロックすることもできるのでしょうか?

たぶん、シグナル・ハンドラーからリストをアクセスするという意味ですね?
であれば、シグナルは待ち行列を持ってないので待たせられないですし、シグナル・ハンドラーはちょっと特殊ですが一種のスレッドですから上記回答に準じます。本当にシグナル・ハンドラーを使わないとできない処理なのか検討されることをお薦めします。
(実は、他のtoma_kazusaさんの質問から、シグナル・ハンドラーを使う必要がないだけでなく、そもそもシグナル・ハンドラーではできないだろうと予想しています。恐らく、複数クライアントからのUDP受信待ちタイムアウト時にそのクライアントの識別情報をリストから削除したいのですよね?)

投稿2016/02/16 01:00

Chironian

総合スコア23272

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問