• ベストアンサー

static変数とマルチスレッド

eroermineの回答

  • eroermine
  • ベストアンサー率18% (83/444)
回答No.2

$cat test.c static int foo; int bar(){ return foo; } $gcc -S test.c gcc は -S でアセンブラ出力 test.s を出します。 $cat test.s .file "test.c" .text .p2align 2,,3 .globl bar .type bar, @function bar: pushl %ebp movl %esp, %ebp movl foo, %eax leave ret .size bar, .-bar .local foo .comm foo,4,4 .ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518" ブロック外のstatic 変数は固定アドレスとなっているのがわかります。 int bar(){ static int foo = 7; dummyfunc(&foo); return foo; } .file "test2.c" .data .p2align 2 .type foo.0, @object .size foo.0, 4 foo.0: .long 7 .text .p2align 2,,3 .globl bar .type bar, @function bar: pushl %ebp movl %esp, %ebp subl $8, %esp subl $12, %esp pushl $foo.0 call dummyfunc addl $16, %esp movl foo.0, %eax leave ret .size bar, .-bar .ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518" 関数内static 変数もレジスタの影響を受けない固定領域であることがわかります。 ブロック内ならどうか。

関連するQ&A

  • クラス内の関数内static変数について

    クラス内の「staticではないメンバ関数内で定義される」static変数の初期化タイミングはいつでしょうか? 自分としてはクラスのインスタンス生成時に初期化されるものだと思っていたのですが、どうもそうでは無さそうだという現象に出会ったもので。 例えば以下のようなサンプルプログラムがあるとします。 --------------------------------------- class TA { public: void func(int i); }; void TA::func(int i) { static int d=0; d += i; std::cout << d << std::endl; } int main() { for(int i=1; i < 3;i++) { TA ta; ta.func(i); ta.func(i); ta.func(i); } } --------------------------------------- これを実行した時、自分としては 1 2 3 2 4 6 という結果を期待していた訳ですが、実際には 1 2 3 5 7 9 という結果になりました。 ということは、もしかしてメンバ変数ではなくともクラス内に現れるstatic変数はstaticなメンバ変数と同等ということなのでしょうか? 実際、上記ソースのforループ内にもう一つclass TAのインスタンスtbを追加してみると、 --------------------------------------- for(int i=1; i < 3;i++) { TA ta; ta.func(i); ta.func(i); ta.func(i); TA tb; tb.func(i); tb.func(i); tb.func(i); } --------------------------------------- 1 2 3 4 5 6 8 10 12 14 16 18 となりました。 (まぁstaticではないメンバ変数に置き換えれば一応解決するのですが、個人的に何か凄く気持ち悪く感じて・・・)

  • static変数について

    struct XXX { char *aaa; char *bbb; }; static struct XXX YYY[] = { {NULL, "JJJ"}, ... }; thread(){ ... } 上記のstatic変数をスレッド関数thread()の外部変数として設定した場合、 *aaaの値はスレッドごとには確保することできませんでしょうか。 上書きされてしまうのでしょうか。 やはりスレッドセーフではないのでしょうか。 その際、どのように設定してあげればよいのでしょうか。 どなたかご教授お願いします。

  • マルチスレッドと変数

    マルチスレッドのプログラムを組んでいます。 そこで、複数のスレッドからアクセスする変数があるのですが、これの扱いについて解らないことがあります。 ・変数を複数のスレッドから書き換える場合は、予想していた結果と違うことになる。 ここまではいいのですが、 ・変数を複数のスレッドから、参照だけするのは問題ない。 ・変数を複数のスレッドから、参照し、書き換えるのはひとつのスレッドだけならば、問題はない。 (上の"変数"は全て、Lockをかけていない状態です。) という認識をもっているのですが、これは間違いなのでしょうか? 「参照だけならばLockはかけなくてよい」というのをどこかで読んだような覚えがあり、そのまま勝手に最後の推測をしています。 現状ではうまくいっているようなのですが、とても不安です。 もしくは、状況、環境、コーディングによって上の仮定は成立したり、成立しなかったりするのでしょうか?環境はC#ですが、もしどのような言語、環境であっても一般的に、同じような結果になるのなら、それも合わせてご教授お願いします。

  • マルチスレッドの疑問点と配列について

    こんばんわ。 VC++.NET2003を用いて、C言語プログラミングを行っています。以下に質問内容をまとめます。 1.現在、マルチスレッドを行っています。マルチスレッドの注意点として、 ・スレッドが複数同時に処理(現在2スレッド)され、それぞれのスレッドで同一のグローバル変数をアクセスする。 ・各スレッドで使用しているスタティック変数はプロセスとして1つの領域に確保される。 と記述されていました。 現在、2スレッド動かしているのですが、2スレッド共通で使用したい変数がある場合は、グローバル変数として宣言してよいのでしょうか? スタティック変数というのは、 static int i を指すのでしょうか・・・・初心者的発言で申し訳ありません。 次にもう一つ質問させていただきます。 配列を整数型で10000要素、静的に用意します。 これを、memset関数ですべての番地に0を初期値として入れておきます。 たとえば、9000という数字があった場合、9000番に整数値9000を格納する。また、56では56番に56を格納する。 そして、最終的に10000要素を走査し0の場所をカウントする。 ということは可能でしょうか?もしよろしければ、サンプルを教えていただきたいと思っています。 よろしくお願い致します。

  • static付き宣言の初期化

    static付きの宣言をした場合の変数の初期化について教えてください。(ANSI-C) int func(void) { static int si; static char sca[10]; static char *scp; /* 何らかの処理 */ return 0; } このように関数内でstatic付きで宣言したとき、変数はどのように初期化されますか? siは0、sca[0]からsca[9]までは'\0'、scpはNULLで初期化されますか? また、このようなstatic付きの宣言が関数の外にあった場合は、どのように初期化されますか?

  • JAVAのマルチスレッドの共有変数についての質問

    JAVAのマルチスレッドの共有変数についての質問です。 スレッドを2つ作ってその2つのスレッド共有の配列を作りたいのですがどうすれば良いのでしょうか。 コードは以下のとおりです。 public class testes extends Thread { int n; int a[]={10,10}; public testes(int n){ this.n = n; } public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ testes t1 = new testes(0); testes t2 = new testes(1); t1.start(); t2.start(); } public void run(){ a[n] =n; System.out.println(a[0]+","+a[1]); } } 実行すると(0,10)もしくは(10,1)が表示されます。 このとき(0,1)と表示するにはどうすれば良いのでしょうか。

  • SAStrutsでServiceのStatic変数

    SAStrutsでServiceのStatic変数の動作で疑問があります。 Eclipse+TomcatでサンプルWebアプリを作成し、以下のサービスをActionから呼び出しています。 これは、Staticなint型の変数に、インスタンスを生成した回数を格納する物です。 public class SampleService{ private static int instanceCnt = 0; public SampleService(){ instanceCnt++; System.out.println(instanceCnt); } } これを何度も呼び出すと、何故かある時突然、出力する数値が1にリセットされるのです。 Static変数はスレッド間で共通で使われているはずなので、これは起こらないはずではないでしょうか? 考えられるとすれば、Tomcatが複数のJavaVMを呼び出して、Webアプリケーションを実行しているのでは、と思うのですが、いまいち確信が持てないのです。 なぜこういう事が起こるのか、詳しい方、教えてもらえないでしょうか。

    • ベストアンサー
    • Java
  • マルチスレッド下でのインスタンス変数・クラス変数

    よろしくお願いします。  マルチスレッド下で動作するクラスを作成しています。データにアクセスするためのオブジェクトを クラスのフィールド値として保持し、使い回しを行いたいと考えています。このデータアクセスオブジェクト(以下Dao)内では特にフィールドは使用せず、全てローカル変数のみで動作するようになっています。Dao自体は初回のクラス生成時にstatic処理にてフィールドにセットされます。  このDaoを保持するフィールドは、staticなクラス変数が良いのか、インスタンス変数として保持する方が良いのか迷っております。  クラス変数ならばPermanent領域をオブジェクト1つ分のメモリ使用で済み、インスタンス変数だとスレッド毎にheapを使い、処理数が増えるとメモリ圧迫しちゃう?と安易に考えてしまったりしています。  ご意見・ご助言よろしくお願い致します。

    • ベストアンサー
    • Java
  • 分割ファイルでstatic変数はどのようにすれば良いのでしょうか?

    1つのファイルでstatic変数を使っている場合は気にしていなかったのですが、分割ファイルにした場合、static変数はどのようにすれば各ファイルで利用できるのでしょうか? 通常のグローバル変数の場合はexternとすれば良かったのですが方法がかわりません。 ** test1.cpp static int a; ** test2.cpp ?????? (二重定義になる) あと1ファイルから分割ファイルにした場合に気をつけるべき点など詳しい方教えて下さい。

  • (マルチスレッド)_beginthreadexに複数の引数を渡す

    現在プログラムでマルチスレッドをやろうとしているのですが、 マルチスレッドの関数に数値や配列などの引数を渡すことは可能でしょうか? MSDNで調べてみると、_beginthreadex関数の4番目のNULLのところに引数リストを 指定できるとあったのですが、その意味が良くわかりませんでした。 以下のプログラムの場合にマルチスレッドに変数a, b, cを引数として渡したい場合は どのように書けばいいのでしょうか? #include <stdio.h> #include <windows.h> #include <process.h> unsigned WINAPI MyThread( void *lpx ){ while (1) { printf("スレッド実行中\n"); Sleep(1000); } return 0; } void main(){ // スレッドに渡したい変数の宣言 int a = 128; int b = 256; int c = 512; // スレッドIDの宣言 DWORD thID; // マルチスレッドの開始 (HANDLE)_beginthreadex( NULL, 0, &MyThread, NULL, 0, (unsigned int*)&thID ); // ループ while (1) { printf("メイン関数実行中\n"); Sleep(2000); } }