• ベストアンサー

リエントランスな関数

最近、リエントランス(re-entrance)な関数という言葉を聞きました。 恥ずかしながら、全然意識したことのない言葉でした。 C言語の標準ライブラリには、リエントランスな関数とそうでない関数があると聞いたのですが、それを調べるにはどのようにしたら良いでしょうか? ANSIの仕様で決まっているのでしょうか? それとも、コンパイラ依存なのでしょうか? 参考書とかHPとかを紹介していただけるとありがたいです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

どちらかというと, 普通は reentrant な関数というような気はします (reentrant は形容詞, reentrance は名詞) が, ISO の仕様として C の標準ライブラリはどれもリエントラントであることが保証されません. 従って, 一般にシグナルハンドラで標準ライブラリを呼び出すことはできません (と, ちゃんと規格に書いてあります). もちろん処理系によってリエントラントであってもかまいませんが, リエントラントであることを前提としたプログラムは移植するときに問題となりえます.

okazaki0ko
質問者

お礼

再入可能であることは、保証されていないということですね。 その結果、割り込みでは使用してはいけない・・・と理解しました。 リエントラントが形容詞なら、それに「な(断定の助詞の連体形)」は付けることはできませんね。 リエントランスは名詞(体言)なので「な(断定の助詞の連体形)」は付けることができますが。 リエントランス関数とは言えないけど、リエントラント関数とは言えますね。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

処理系に依存するので, 特定の標準ライブラリ関数がリエントラントかどうかを調べるにはその処理系の資料を読むしかないです. まあ, 明らかにリエントラントでない標準ライブラリ関数はありますが. 念のためですが, 規格では 「標準ライブラリ関数がリエントラントであることを保証しない」 The functions in the standard library are not guaranteed to be reentrant つまり「リエントラントであってもいいしリエントラントでなくてもいい」であって, 「すべて非エントラント」であると規定しているわけではありません>#4... もちろんプログラムを書く上では (すべての関数がリエントラントでないことを想定しなければならないので) 実質的に同義ですが, そんな規定はだれにとっても困るだけ.

okazaki0ko
質問者

お礼

> 処理系に依存するので, 処理系依存のプログラムは書きたくないので、処理系依存の部分は排除したいと思います。 ただ、OSを設計(模倣)していますので、どうしてもマシン依存=処理系依存があるのですが、最低限に抑えたいのです。 >「標準ライブラリ関数がリエントラントであることを保証しない」 ということで、再入可能ではないことを前提に設計して行きたいと思います。 リエントランス・リエントラントについては、#2のお礼を見てください。

全文を見る
すると、全ての回答が全文表示されます。
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.5

追記。 ANo.4の回答では「fopenは非リエントラントな関数」と回答しましたが、実装を工夫し、以下のようにすれば「リエントラントな関数」になります。 ・システムコールでファイルを開く ・ファイルがオープン出来なければエラーで帰る ・割り込み禁止にする ・ファイル識別子の空きを探し、空きが無かったら、ファイルを閉じ、割り込み禁止解除をして、エラーで帰る ・空きがあったら、それを使用済みに書き替える ・割り込み禁止解除し、ファイル識別子のポインタを戻り値にして帰る これで「空きを探して、使用済みに変え、それを返す」までの間、他のスレッドや割り込み処理ルーチンに切り替わる心配はないので「リエントラントな関数」となります。 とは言え「使っているコンパイラのfopenが、こういう親切な実装をしてくれてるかどうかは、実際に実装した人にしか判らない」ので「使う側は、非リエントラントだと思って、安全な使い方をするしかない」のです。

okazaki0ko
質問者

お礼

OSの設計をしているので、OS依存の関数を使うことはないのですが、 > とは言え「使っているコンパイラのfopenが、こういう親切な実装をしてくれてるかどうかは、実際に実装した人にしか判らない」ので「使う側は、非リエントラントだと思って、安全な使い方をするしかない」のです。 この方針で行くことにしました。

全文を見る
すると、全ての回答が全文表示されます。
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.4

「リエントラント」ですね。 基本的には「その関数が終了して呼び出し元に復帰する前に、誰かが同じ関数を呼んだ場合、正常に動作するかどうか?」で「リエントラントな関数」か「リエントラントでない関数」かが決まります。 通常、静的メモリを操作しする関数は「リエントラントでない関数」と思って間違いありません。 例えば、fopenは、静的メモリに配置された「ファイル識別子」を返します。簡単に言えば「FILEへのポインタ」です。なので、fopenは「リエントラントでない関数」です。 fopenは、未使用のファイル識別子を探し、空きがあれば、システムコールでファイルを開き、開けたら、ファイル識別子を使用済みに書き替え、そのファイル識別子を返します。 この処理が「2つのスレッドで、ほぼ同時に起こった」としたら、どうなるでしょう? 1.スレッド1でfopenを呼んだ。 2.スレッド1は、静的メモリに配置された未使用のファイル識別子を探し、5番に空きがあったので、システムコールでファイルを開こうとした。 3.システムコールが呼ばれたので、スレッド2に切り替わった。 4.スレッド2でfopenを呼んだ。 5.スレッド2は、静的メモリに配置された未使用のファイル識別子を探し、5番に空きがあったので、システムコールでファイルを開こうとした。 6.システムコールが呼ばれたので、スレッド1に切り替わった。 7.スレッド1が呼んだfopen関数は、ファイルが開けたので、5番を使用済みにして、5番のファイル識別子を返した。 8.スレッド2に切り替わると、スレッド2が呼んだfopen関数は、ファイルが開けたので、5番を使用済みにして、5番のファイル識別子を返した。 このように、2つのスレッドのfopenで「同一のファイル識別子(上記の例では5番のファイル識別子)を返されてしまう」ので、動作が不安定になります。 本当であれば、fopenを呼んだ順に、5番、6番のファイル識別子が返されねばなりません。 で、仕様上は「C標準ライブラリ関数は、すべて非エントラント」ですが、処理系によっては、実装の際に「エントラントな関数」として実装される事もあり「事実上、エントラントか非エントラントかは、処理系に依存する」と言うのが現状です。

okazaki0ko
質問者

お礼

> 通常、静的メモリを操作しする関数は「リエントラントでない関数」と思って間違いありません。 この点がポイントになることは、解っていました。 さて、どの関数が静的領域をいじるのか? それを調べる方法は果たして存在するのか? 仕様で決められていれば楽なのに・・・。 と言った所です。 ですので、 > で、仕様上は「C標準ライブラリ関数は、すべて非エントラント」ですが、 で、解決です。 リエントランス・リエントラントについては、#2のお礼を見てください。

全文を見る
すると、全ての回答が全文表示されます。
回答No.3

「リエントラント(再入可能)」な関数  とは、当該関数実行中に、他のスレッドなどからさらに実行が可能  な実装仕様を言います。一般にWindowsのコールバック関数及び一  群のメッセージ処理関数群はリエントラントであることが要求され  ていますが、そうでなくても再入しない場合がほとんどなので動い  ちゃいます(笑)。但し、DLLの関数はリエントラントであることが  より強く要求されます。  似たように言葉に「リカーシブ(再帰可能)」がありますが、こちら  の条件は当該関数から当該関数をコールしても動作することです。  ニーモニックレベルだと「リロケータブル」というのも良く言われ  ますが、特別に処理しない限り、C言語では全てリロケータブルに  翻訳されます。

okazaki0ko
質問者

お礼

今回は、OSの設計でぶつかった問題でした。 なので、パソコンのOS類のお世話にはならない訳ですが(組み込み系の設計です)、DLLが再入可能である必要があることは、良く解ります。 リロケータブルは、ちょっと今回の件とは関係ないような・・・。 リエントランス・リエントラントについては、#2のお礼を見てください。

全文を見る
すると、全ての回答が全文表示されます。
  • eroermine
  • ベストアンサー率18% (83/444)
回答No.1

thread safe で検索すればわかると思います。 昔はリエントラントと言ってましたね。SUN4あたりからそういう用語が出てきたかと。 The GNU C library uses thread safe functions by default and libc5 used non thread safe versions. これはなんか gcc のlibcが遅いとか言う苦情にたいする反論。 コンパイラにオプションがあったりもします。 言語によってはリエントラント関数にはなにか特別な識別子があったりもします。 今思い出せない。 参考書よりも検索しまくりでどうぞ。

okazaki0ko
質問者

お礼

> thread safe で検索すればわかると思います。 > 参考書よりも検索しまくりでどうぞ。 検索用キーワードを教えていただいたので、検索かけてみます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語のライブラリ関数の勉強の仕方

    はじめまして、私はC言語を勉強中の初心者です。 基本的な構文などを理解して、標準ライブラリ関数を勉強して行こうと思ったのですが、うまく勉強できずに苦戦しています。そこで2つ聞きたいことがあります。 1.普通標準ライブラリ関数はどの程度覚えるものなのでしょうか? 徹底的に網羅するのか、一般的なところは押さえて後は適当にやるのか、などを知りたいです。 2.関数はどうやって勉強したらいいのでしょうか? 私は細かいところまで徹底的に覚えたいタイプで、今は、自分のコンパイラ(VC++ 2008)のincludeフォルダにあるヘッダファイルを調べ、関数のプロトタイプ宣言をしてあるところを見つけて関数名を洗い出し、その関数名で検索を掛けて関数を覚えていく、という方法を取っているのですが、これだと恐ろしく効率が悪いです。皆さんはどうやってライブラリ関数について勉強していったのでしょうか? 質問したいのは上記の2点です。回答よろしくお願いします。

  • 標準ライブラリー関数を使用せずに文字出力

    はじめまして、C言語初心者です。 研修で、C言語を学ぶことになったのですが研修先から頂いた練習問題で「練習のため標準ライブラリー関数は使わない」で文字列を連結するための関数を作ることになったのですが、標準ライブラリー関数を使用せずに文字出力はできるのですか??

  • 標準ライブラリ関数

    C言語の勉強を始めたばかりです。 標準ライブラリ関数というのがたくさんありますが、実際のソースをのせているサイトってありませんか?たとえばstrcmpを使わずにアルファベット順に並べ替えるプログラムを作ってみたいのですが。お願いします。

  • 「数学」に標準規格は存在しないのでしょうか

    例えばプログラミング言語では変数名,定数名,関数名の命名規約があり, 数値には整数型,浮動小数点数型などの型が必ず与えられていたりと その言語の仕様が厳密に定義されています. IT分野では標準規格としてANSI,ISO,JIS,RFCなどさまざまな物がありますが, 「数学」ではそういった標準規格なるものは存在しないのでしょうか. 今まで見たことも聞いたこともなかったので質問させていただきました. よろしくお願いします.

  • 関数ライブラリ一覧

    C言語の関数一覧のようなものは何を見たらわかるのでしょうか? 標準関数の一覧はよく見かけますが、ほかの関数の一覧はないのでしょうか? たとえば、あるインターネット上で公開されていたソースコードには #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <sys/param.h> #include <sys/uio.h> #include <unistd.h> と書いてありました。 上3つは標準ライブラリにかいてありますが、その他は載ってません。 こういったsys/uio.hなどの仕様はどこで見れるのでしょうか? よろしお願いします。

  • プログラミングの勉強

    独学で言語をまなんでいるのですが、どこまでやれば一通りは学べたとして次の言語に進めるのでしょうか?文法はとうぜんとして、標準ライブラリ関数などはどこまでおぼえるものでしょうか?

  • コンソールプログラムで使用するライブラリについて

    今まで疑問に感じつつないがしろにしていた部分なんですが、 例えばWin32APIを使用してプログラミングする時にコンパイラはリンクの際にwindowsのシステムフォルダ内にあるdllファイルを参照してリンクするんですよね(あってます?)?ではコンソールプログラム(dos上のプログラム)をリンクする際にはどうなるのでしょうか(例えばCの標準関数のライブラリはどこにあるのでしょうか?)? 私の予想では標準関数に関してはコンパイラが予め用意している静的ライブラリを使ってリンクしているんじゃないかと思うのですが実際どうなんでしょうか? 大した質問でもないのに長々とした文章になってしまいましたがよろしくお願いします。

  • peace関数について

    hp、ANSIで作成された関数を他のUNIX環境(Solaris2.5.x)に移植しようとしています。 その中でpeaceという関数でコンパイルは通るのですが、EXEが生成できません。 p = peace(p, tmp, ':'); これはどういった理由が考えられますか? 結構はまっています。自作の関数ではないと思うのですが・・・ 環境に依存しているのでしょうか? よろしくお願いします。 以下のようなエラーが出ます。 % !cc cc -o comGetExePath.exe *.o 未定義の 最初に参照している シンボル ファイル peace comGetExePath.o ld: 重大なエラー: シンボル参照エラー。comGetExePath.exe に書き込まれる出力はありません

  • H8/3048で三角関数の使い方について

    H8/3048の三角関数の使い方について質問です。 現在秋月の付属コンパイラを使用しているのですが、 標準ライブラリに三角関数などが無いため使えません。 下記のようなサイトを見つけたのですが、内容が理解出来ません。 何とか使用したいのですが、どの様にすればよろしいでしょうか? 宜しくお願いいたします。 http://www.bblab.com/index.php?H8-3048F%A5%AF%A5%ED%A5%B9%B3%AB%C8%AF%B4%C4%B6%AD#content_1_2

  • 標準ライブラリ関数の自作について質問です。

    C言語初心者の学生です。 標準ライブラリ関数のstrncpyと同じ機能の関数を自作でつくる場合どのようにすれば良いでしょうか。 mystrncpy(char *s1,char *s2,int n) { } かっこの間を埋める形でお願いします。 同じようにstrncat、strnchr、strnstrも答えていただけると幸いです。 すべてではなく4つのうち1つからでも結構ですのでよろしくお願いいたします。