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

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

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

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

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

x86

x86はIntel 8086 CPU シリーズの命令セットアルキテクチャーです。

Q&A

3回答

3265閲覧

シグナルハンドラ内では非同期安全関数を使わなければいけないが・・・?

kazuyakazuya

総合スコア193

C

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

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

x86

x86はIntel 8086 CPU シリーズの命令セットアルキテクチャーです。

0グッド

1クリップ

投稿2020/08/02 02:26

編集2020/08/03 02:41

まず私が考えている言葉の定義

リエントラント・・・あるプログラムやサブルーチンの実行を完了する前に、割り込みなどにより、同じプログラムやサブルーチンを実行しても安全だという性質を指す。

非同期安全関数・・・上記を達成するための手段としてセマフォ、スピンロックなどの同期プリミティブを使ってはならない。
同期プリミティブを使わずリエントラントを達成したもの。

シグナルハンドラ内部では非同期安全関数を使わなければならず
スピンロックなどの手段を使っているリエントラントな関数を呼びだすのもNG
(デッドロックするみたい)
割込みハンドラ(ハードウエア割り込み)、例外ハンドラ内部では非同期安全関数は使う必要はありますか?

自分はする必要があるんじゃないかと思っていますが・・・

一応調べましたが
割り込みハンドラ内では非同期安全関数を使いましょう。
といったようなことが書かれている記事はみたことがありません。

知ってて当たり前だから省略されて書かれていないのかな・・・?

環境はx86,OSはLinuxを前提にお願いします。

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

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

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

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

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

maisumakun

2020/08/02 02:33

「例外ハンドラ」とは、どのような例外に対応するハンドラでしょうか?(C++例外の処理であれば、特段の制約はかかりません)
kazuyakazuya

2020/08/02 02:38

すみません そのような例外 という言葉の意味がわかりません。 ・フォルト ・トラップ ・アボート ・ソフトウエア割り込み といった例外の中での分類の話ですか?
maisumakun

2020/08/02 02:42 編集

なるほど、CPU側の例外ハンドラということですね。ありがとうございました(CPUレベル、OSレベル、言語レベルといった区分での疑問でした)。
kazuyakazuya

2020/08/02 02:42

CPU例外以外の例外とは何でしょうか? if() else() とかそういう (言い方が適切かわからないが) C言語ならCレベルでの例外(?)ってことですか?
maisumakun

2020/08/02 02:44

上にコメントしたように、C++など、多くの言語に言語内の例外処理が設けられています。
maisumakun

2020/08/03 02:12 編集

そもそも、一般的にはCPUレベルの割り込みや例外をユーザー側が書くコードで処理すること自体ないかと思いますが、どのような環境(チップ・OS)で動くコードなのでしょうか?
kazuyakazuya

2020/08/03 02:39

いえ、実際に書かなければいけない状況になったわけではなく ただただ気になっただけです。 そういう細かいところも知りたいです
maisumakun

2020/08/03 02:43

「気になっただけ」にしても、実際にどのような環境で動かすのかがはっきりしないと、「環境依存」としか言えません。
kazuyakazuya

2020/08/03 02:46

x86,Linux以外に必要な情報がありましたら教えてください。 (自分はこれ以上思いつかなかったが・・・)
guest

回答3

0

割込みハンドラ(ハードウエア割り込み)、例外ハンドラ内部では非同期安全関数は使う必要はありますか?
環境はx86,OSはLinuxを前提にお願いします。

このような環境であれば、CPUレベルの割り込みや例外はすべてOSが管理するので、自分でハンドラを書いてはいけない(Linuxを経由せずにセットしようとしても正常に動作しない)のではないでしょうか。

投稿2020/08/03 02:46

maisumakun

総合スコア146018

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

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

maisumakun

2020/08/03 02:48 編集

どのようなシチュエーションで、自前のハンドラを(OSと別枠で)セットすると想定したのでしょうか?
kazuyakazuya

2020/08/03 02:52 編集

すみません。自分の説明が悪かったです 最終的に自作OSを作りたいと思っています。 その自作OS上の割り込みハンドラ・例外ハンドラを自分で設定する際 シグナルハンドラのように非同期安全関数を使う必要があるのか?ということで質問いたしました。 >このような環境であれば、CPUレベルの割り込みや例外はすべてOSが管理するので、自分でハンドラを書いてはいけない(Linuxを経由せずにセットしようとしても正常に動作しない)のではないでしょうか。 まぁ、確かにそうですが・・・
maisumakun

2020/08/03 03:02

例外ハンドラでは「絶対に例外を起こしてはいけない」(例外が起きればダブルフォールトで死ぬ)ので、そういった意味での安全性を確認した関数しか呼べません。一般の関数をホイホイ呼んでいい場所ではありません。
kazuyakazuya

2020/08/03 03:39

>例外ハンドラでは「絶対に例外を起こしてはいけない」 それは知りませんでした ありがとうございます。 では、一般的に言われる非同期安全関数はどうなのでしょう?
maisumakun

2020/08/03 03:39

> では、一般的に言われる非同期安全関数はどうなのでしょう? それより条件は厳しいです。
kazuyakazuya

2020/08/03 03:46

例外ハンドラ・割込みハンドラ内で使っていい関数に条件を付けるとしたら 非同期安全保障 + 絶対に例外を起こさない保証(カーネルコードはバグがないことを前提) という感じですか?
maisumakun

2020/08/03 04:49

…というより、例外ハンドラから、どの関数を呼びたいのですか? 例外ハンドラは最低限の処理しかさせないものなので、ライブラリ関数を呼ぶこと自体がイレギュラーかと思います。
dodox86

2020/08/03 16:26

横から失礼します。 >@kazuyakazuyaさん > 最終的に自作OSを作りたいと思っています。 > その自作OS上の割り込みハンドラ・例外ハンドラを自分で設定する際 > シグナルハンドラのように非同期安全関数を使う必要があるのか?ということで質問いたしました。 その論点でいえば、自分の最終的にやりたいように実装すれば良いのではないでしょうか。そういったものを実装しているLinux、その他現行のUN*X系OSは、POSIXを意識しています。 (Linuxを造ったLinus Torvalds氏も、開発の当初、POSIXの仕様書を求めていた逸話があります)Linuxや現行のOSを理解する上でそれらを意識して読むことは必要だと思いますが、それを踏まえた上でその制限に縛られないモノを造ろうとするのはkazuyakazuyaさんの自由のはずです。話はもどって、「現行のLinuxでそういった制限がある理由、あるいはそれを明記したものがあるのか」と言う疑問を解決するのが目的なのであれば、それはそれで良いとは思いますが。
kazuyakazuya

2020/08/04 02:38

確かに自作OSなので設計をどうしようと自分の勝手ですが ここの部分に関してはLinuxになぞって作ってみたいのです。 ここ基本的な(根本的な?)部分を知りたいです。 使う場面あるかって言われたらほぼないだろうけど・・・。 >それを踏まえた上でその制限に縛られないモノを造ろうとするのはkazuyakazuyaさんの自由 シグナルハンドラ内で非同期安全関数を使う では 割り込み・例外ハンドラ内では?という部分が的確にわからないのに それを応用(?)した仕組みを作るとなると いつか穴(?)があきそうですが・・・
maisumakun

2020/08/04 02:42

「必要になってから考える」式で問題ないのではないでしょうか? (上にコメントしたように、CPUが直接実行するハンドラでは最低限の処理だけで済ませるべきものです)
dodox86

2020/08/04 02:49

ハードウェア割込みが複数発生した場合(割込みハンドラ中で更に発生)のことを考えると、非同期安全関数のみを使うようになった理由が垣間見えるかもしれませんね。実際にそれが理由だったかは分かりませんが、多重割込みや他プロセスが動いてしまうようなメカニズムを仕様として許してしまうと、複雑で問題が起きやすくなるのは比較的簡単に想像できると思います。割込みやシグナルハンドラの処理は極力短く、複雑なことは上位に任せるのが基本的な方針です。(<トップハーフ・ボトムハーフ)
kazuyakazuya

2020/08/04 08:57

つまり、割り込みハンドラ内でも基本的に非同期安全関数を使わなければいけないってことですか?(原点戻るけど)
maisumakun

2020/08/04 09:02 編集

ですから、「どんな関数を使いたい」、もっと言えば「どんな処理をそこで行いたい」のですか?
maisumakun

2020/08/04 09:14

> 基本的に非同期安全関数を使わなければいけないってことですか? 基本的には「ライブラリ関数を呼ぶべきではない」(把握できる少量のコードだけ実行すべき)場面と考えます。
kazuyakazuya

2020/08/04 11:47 編集

>ですから、「どんな関数を使いたい」 どういうことですか? 非同期安全関数という幅広い範囲ではなくもっと絞れってことですか? (正直ある特定の関数を使いたい!ってのはありませんが・・・)
maisumakun

2020/08/04 11:42

> 非同期安全関数という幅広い範囲ではなくもっと絞れってことですか? はい。すでに書いたこととも重なりますが、その状況で呼んでよい関数なのかどうかは1つ1つ吟味する必要がある、と考えます。 > 正直ある特定の関数を使い方!ってのはありませんが・・・ でしたら「呼びたくなってから考える」で問題ないかと思います。
kazuyakazuya

2020/08/05 03:24

すみません 以下のどっちの意味ですか? ・割り込みハンドラ内で呼ぶ関数は非同期安全関数であればなんでもかなわない というわけではないかもしれない
maisumakun

2020/08/05 03:26

選択肢が1つしか示されていないようですが?
kazuyakazuya

2020/08/05 03:56

あれ・・・? もう一回載せますね。 ・割り込みハンドラ内で呼ぶ関数は非同期安全関数であればなんでもかなわない というわけではないかもしれない ・割り込みハンドラ内で呼ぶ関数は必ずしも非同期安全関数でなければいけない というわけではないかもしれない
maisumakun

2020/08/07 02:49 編集

すみません、「ないかもしれない」で中途半端に否定されたために、どう答えていいのかよくわからなくなっています。 選択肢を無視して答えれば、「1つ1つ考える必要がある(たぶん非同期安全でない関数は全滅だろうけど)」です。
maisumakun

2020/08/07 02:56 編集

なぜ「非同期安全かどうか」にこだわりつづけているのですか? 自分の回答としては、「非同期安全かどうか」という分類は、この場面において有意でない、という主張です。
kazuyakazuya

2020/08/07 06:18

う~ん、そうですか。 では実際に割り込みハンドラを設定するとき 内部で呼ぶ関数は最低条件として「非同期安全保障」のうえ、本当にそこで呼んで問題ないか確認するということで・・・
guest

0

割り込みハンドラ内では非同期安全関数を使いましょう。
といったようなことが書かれている記事はみたことがありません。

JPCERT CC「SIG30-C. シグナルハンドラ内では非同期安全な関数のみを呼び出す

POSIX仕様を定める IEEE Std 1003.1-2017, 2.4.3 Signal Actionsには 非同期シグナルセーフ(async-signal-safe) な関数を列挙しています。


環境はx86,OSはLinuxを前提

Linuxでのハードウェア割り込み処理は、デバイスドライバとして実現されます。

たとえば Linux Device Drivers, 3rd Ed., Chap10. Interrupt Handling, Implementing a Handler では、下記のように説明されています。

The only peculiarity is that a handler runs at interrupt time and, therefore, suffers some restrictions on what it can do. These restrictions are the same as those we saw with kernel timers. A handler can't transfer data to or from user space, because it doesn't execute in the context of a process. Handlers also cannot do anything that would sleep, such as calling wait_event, allocating memory with anything other than GFP_ATOMIC, or locking a semaphore. Finally, handlers cannot call schedule.

The role of an interrupt handler is to give feedback to its device about interrupt reception and to read or write data according to the meaning of the interrupt being serviced. The first step usually consists of clearing a bit on the interface board; most hardware devices won't generate other interrupts until their "interrupt-pending" bit has been cleared. Depending on how your hardware works, this step may need to be performed last instead of first; there is no catch-all rule here. Some devices don't require this step, because they don't have an "interrupt-pending" bit; such devices are a minority, although the parallel port is one of them. For that reason, short does not have to clear such a bit.

投稿2020/08/02 03:16

編集2020/08/03 08:23
yohhoy

総合スコア6191

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

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

kazuyakazuya

2020/08/02 11:07

シグナルハンドラと割り込みハンドラは明確に違うはず。 JPCERT CC「SIG30-C. シグナルハンドラ内では非同期安全な関数のみを呼び出す」 ここではシグナルハンドラに関してしか記述されていないように見えるのですが
yohhoy

2020/08/03 02:07 編集

質問の主題は「ソフトウェア割り込み=シグナル」ではなく「ハードウェア割り込み」でしょうか? OSに強く依存すると思いますので、そのあたりを明記されたほうが宜しいかと。 JPCERTやPOSIX引用はいずれもユーザランド・アプリケーションを対象にした話かと思います。
kazuyakazuya

2020/08/03 15:35

ありがとうございます、読んでみます
guest

0

ハードウエア割り込み内ではセマフォ、スピンロックなどの同期プリミティブってのは使えません。
それらは、あくまでOSでの非同期実行を行うための関数なので、ハードウエアレベルでは意味を持ちません

投稿2020/08/02 02:30

y_waiwai

総合スコア88042

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

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

kazuyakazuya

2020/08/02 02:40

ハード割り込みにおいて同期プリミティブが意味を持たない理由がわかりません。 もうちょっと詳しく教えていただけると助かります ハードウエア割り込みは非同期に発生しますが それは同期プリミティブを使えない理由にはならない気がしますが。 (Linuxにおいてのシグナルは受け手から見れば同期ともいえるかな)
y_waiwai

2020/08/02 02:46

それらはOSの機能として用意されてるってことはわかりますか? しかし、ハードウエア割り込みはOSで発生するものではありません
kazuyakazuya

2020/08/02 02:54

同期プリミティブ・シグナルはOSの機能だということは理解しています。 ハードウエア割り込みは非同期に外部デバイスがトリガーとなり発生しますが トリガーによって発生する内容というのはOSが決められるはずです。 その内容(割り込みハンドラ)に同期プリミティブの仕組みを取り入れることもできるんじゃないかと思うのですが
dodox86

2020/08/02 03:25

アプリのシグナルハンドラ、ハードウェア割込みに起因するLinuxカーネルの割込みハンドラ、デバイスドライバーの話のレベルが交錯している気がしますが、ハードウェア割込みでのデバイスドライバーの割込みハンドラー内において、スピンロック、セマフォなどのLinuxカーネルの用意した同期、待機メカニズムは使えるか使えないか(=コードとして呼び出せるか)で言ったら、使えます。セマフォに関しては、ハードウェア割込みハンドラの中で即、使うような状況はちょっと思い付きませんが。以上、コメントのみです。もちろん、間違いのご指摘があれば受け付けます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問