• ベストアンサー

__threadを使うコードで、分割コンパイル→リンクを行うには?

下記コードをビルド中、下記リンカエラーが出てしまい その解決方法を伺いたく質問させて頂きました。 ■コード [ t.hpp ] struct C { static int m; static void f(); }; [ a.cpp ] #include "t.hpp" __thread int C::m; [ b.cpp ] #include "t.hpp" void C::f(){ m = 0; } void main(){} ■リンカエラー C::m: TLS definition in a.obj section .tbss mismatches non-TLS reference in Debug/b.obj (静的メンバ変数C::mは a.cppでTLSとして定義されたけど、C::mを参照しているb.cppでは、非TLS扱いだから合わないよ!) ■試した事 ・t.hppのstatic int m; に、__threadを付加 → 付けないのと同じ扱いだった ・a.cppのコードをb.cppに統合したらOK → __thread変数の定義部と参照部を同じファイルにすると良さそう。が、会社の政治的な理由で不可... ■環境 ある組み込み環境でのGCC4.0.2 一日中試しましたが惨敗でした。ファイル構成を変えずにTLSの静的メンバ変数が使える方法をお教え頂けないでしょうか。どうか宜しくお願い致します。

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

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

__threadって初めてみるので、勉強を兼ねてサンプルを書きました。 以下のような感じでコンパイルは通りました。 環境はgcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) ■test.h #ifndef __TEST_H_ #define __TEST_H_ struct C {   static __thread int m;   static void f(); }; #endif ■main.cpp #include "test.h" #include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <unistd.h> void C::f() {   m++;   printf("id = %d: m = %d\n", pthread_self(), m); } void * func(void *arg) {   sleep(1);   C::f(); } int main() {   pthread_t tid0, tid1;   pthread_create(&tid0, NULL, func, NULL);   pthread_create(&tid1, NULL, func, NULL);   pthread_join(tid0, NULL);   pthread_join(tid1, NULL); } ■main2.cpp #include "test.h" __thread int C::m = 0; ■実行結果 id = 1084726192: m = 1 id = 1093114800: m = 1 (それぞれのスレッドでm++しているが、値は1) 質問者さんのソースがどうなっているのかよくわかりませんが、 参考になりますでしょうか。

noname#32535
質問者

お礼

カスタム版GCCの修正担当者が、バグを仕込んでしまったようです。 別の版(新旧)を試したら、問題がおきませんでした。 ので、修正を待つ事に致します。どうも有難うございました。

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

その他の回答 (1)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> ある組み込み環境 ここを明確にしないとどうしようもないのでは? Linuxのような__threadをサポートしている環境ならできるでしょうが、μITRONなどで__threadを付けても無意味です。

noname#32535
質問者

お礼

有難うございます。環境はLinuxベースの環境です。具体化したいのは山々ですが、これ以上公に出来ない状況です。 又、__threadが意味を成す環境です。

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

関連するQ&A

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );

  • c# スレッド間でのデータの共有

    C#でメインプロセスと生成されたスレッド間でデータの共有をさせたいのですがどのようにすればいいのでしょうか。ご教授お願い致します。 ・メインプロセス(A) ・Aから生成されたスレッド(B) 例えば、AとBで変数の値をそれぞれ読み書きさせたい場合 どのようにすればよいのでしょうか。 class TEST { public int flag; // メインプロセス(A) public static void Main() { Thread t = new Thread(new ThreadStart(abc)); t.IsBackground = true; t.Start(); while(ture) { Thread.Sleep(10); Console.WriteLine("A:{0}",flag); } } // Aから生成されたスレッド(B) public void abc() { Console.WriteLine("B:{0}",flag); flag++; } }

  • LKMの分割コンパイルについて

    こんばんは、自分は今LKMの分割コンパイルに挑戦しています。 以下のようなファイルを作成して、モジュールを作ってみました。 [Makefile] obj-m := message.o message-objs := message.o sample_func.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -f *.o *.ko *.symvers *~ *.mod.c [message.c] #include <linux/module.h> #include <linux/kernel.h> #include "sample_func.h" static char *msg = "[message.o]:"; static int message_module(void) { printk(KERN_INFO "%s loaded\n",msg); printk(KERN_INFO "%s %d\n", msg, sample_add(2,3)); return 0; } static void message_remove(void) { printk(KERN_INFO "%s removed\n", msg); } module_init(message_module); module_exit(message_remove); [sample_func.c] #include "sample_func.h" static int inner_add(int,int); int sample_add(int a, int b) { return inner_add(a,b); } static int inner_add(int a, int b) { return a+b; } [sample_func.h] int sample_add(int,int); コンパイルは正しく通るようなのですが、/var/log/messages に何も出力がありません。 (KERN_INFOを指定しているので/var/log/messagesに出力されると思っているのですが。。。) lsmodで確認したところ、モジュールはカーネル内に正常に組み込まれているようでした。 どなたか解決方法をご存知の方教えていただけないでしょうか。 宜しくお願いします。

  • 分割コンパイルの初歩

    C言語ですが、.hに実装を書くのは避けたほうが良いといわれます。 私は main.c define.h aaa.h bbb.h みたいなスタイルでコードを書いていました。 まずdefine.hでグローバル変数や、マクロなどの宣言を まとめて行い、ほかの.hやmain.cでも使えるようにして いました。 しかし、以下のような状況のとき、どのように分割すれば 良いのかが分かりません・・・。 たとえば、以下のように、マクロNUM、変数a,bをすべてのファイルで共有して使えるように分割コンパイルするにはどのようにコードを書き直せば良いのでしょうか? //--------------main.c------------------ #include "define.h" #include "aaa.h" #include "bbb.h" int main( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM);   aaa();   bbb();   return 0; } //------------define.h------------------ #define NUM 100 int a = 10; int b = 20; void aaa( void ); void bbb( void ); //------------aaa.h------------------ void aaa( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); } //------------bbb.h------------------ void bbb( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); }

  • C++のファイル分割でのエラーについて

    最近VC2008でC++の勉強を始めたのですが、ファイル分割でLNK2005エラーというのが発生し、解消できません。 インクルードガードは行ったのですが、どうしたらよいのか分かりません。 ソースコードはこんな感じです。 //main.cpp #include "sub.h" #include "res.h" bool main(){ calcx(m_x); calcy(m_y); } //res.h 共有変数の宣言 #ifndef __RES_H #define __RES_H int m_x; int m_y; #endif //sub.h 関数のプロトタイプ宣言を行う void calcx(); void calcy(); //sub.cpp 関数の定義を記述する #include "res.h" void calcx(int x){ m_x = x + 100; } void calcy(int y){ m_y = y + 200; } エラー: 1>Main.obj : error LNK2005: "int m_x" (?m_x@@3HA) は既に sub.obj で定義されています。 1>Main.obj : error LNK2005: "int m_y" (?m_y@@3HA) は既に sub.obj で定義されています。 上記のようなエラーを解消するにはどうしたら良いのでしょうか。 何がおかしいのか指摘をお願いします。

  • 交互にスレッド実行 (どうしてちゃんと動いてる?)

    http://oshiete1.goo.ne.jp/qa2968378.html で質問した者です。 2つのスレッドで1と2を交互に実行する以下のプログラム。 final Object obj1 = new Object(); //スレッド間通信用のobject final Object obj2 = new Object(); //スレッド間通信用のobject2 Thread t1 = new Thread() {  public void run() {   try {    while(true) {     System.out.print("1");     synchronized (obj1) {      synchronized (obj2) {       obj2.notify();//相手をnotifyして      }      obj1.wait();//自分はwait     }    }   } catech (Exception e){} }; Thread t2 = new Thread() {  public void run() {   try {    while(true) {     System.out.print("2");     synchronized (obj2) {      synchronized (obj1) {       obj1.notify();      }      obj2.wait();     }    }   } catch (Exception e){}  } }; Thread t1 = new Test1(); Thread t2 = new Test2(); t1.start(); while(t1.getState() != Thread.State.WAITING); t2.start(); が思ったように動いてはいるものの、なぜ正常に動いているかがわかりません。 t1が wait() したときはobj1のロックをもっていて、t2の synchronized (obj1){obj1.notify()} ブロックに入れず待機するはずだと思うのですが。 なぜちゃんと動いているのでしょう?

    • ベストアンサー
    • Java
  • java コンパイルエラー (初心者です)

    次のようなソースコードを入力してコンパイルすると、 class, interface, or enum expectedというエラーが出ます。 なぜでしょうか?{}の数はあってると思いますが... dentaku.java class dentaku{ public static void main (String args[]){ //3つの変数「a」と「b」と「c」を宣言 int a =0; int b =1; int c =1; System.out.println("xを10進数,aを2進数の1の位、bを10の位、cを100の位とするとと" + (x=a^2+b^2+c^2) + "です。"); } }

    • ベストアンサー
    • Java
  • Javaのスレッドに関して質問です

    Assistantクラスを使い待機状態と再開を確認できるプログラムの作成 loafとrestartメソッドを設ける workメソッドが呼ばれる度loafを呼び出す Managerクラスを定義 checkメソッドを設け、Assistantをcheckし続ける loaf状態ならrestartさせる (Managerクラスはデーモンスレッド) ということなんですが、いまいちうまくいきません さぼっても復帰してくれません public class Assistant implements Runnable { private String name; private Chore c; public Assistant(String name, Chore c) { this.name = name; this.c = c; } public void run() { work(); } public void work() { while (true) { synchronized (c) { if (c.doEnd()) break; System.out.println(name + " : " + c.digest()); loaf(); } } } public synchronized void loaf() { try { c.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void restart() { c.notify(); } } public class Chore { private String name; private int step; private int id; public Chore(String name) { this.name = name; this.step = this.name.length(); this.id = 0; } public synchronized String digest() { String message = "" + id + name.charAt(id); try { Thread.sleep(500); } catch (InterruptedException ie) { } id++; return message; } public synchronized boolean doEnd() { return id >= step; } } public class Manager extends Thread { private String name; private Assistant a; public Manager(String name) { this.name = name; } public void run() { check(); } public void check() { a.restart(); } } public class Test { public static void main(String[] args) { Chore[] ch = { new Chore("掃除"), new Chore("プリント印刷"), new Chore("出欠データ入力") }; Assistant[] a = { new Assistant("あ", ch[0]), new Assistant("\tい", ch[1]), new Assistant("\t\tう", ch[2] }; Thread[] t = new Thread[a.length]; for (int i = 0; i < t.length; i++) { t[i] = new Thread(a[i]); } for (int i = 0; i < t.length; i++) { t[i].start(); } Manager m = new Manager("監査"); m.setDaemon(true); m.start(); for (int i = 0; i < t.length; i++) { try { t[i].join(); } catch( InterruptedException ie ) { } } }

    • ベストアンサー
    • Java
  • MinGWのg++で分割コンパイルエラー

    MinGW環境でC++の勉強を始めました。 簡単なサンプルのコンパイルをしてみたのですが、ソースファイルを一括してコンパイルすると問題ないのですが、個別にコンパイルしようとするとエラーがでてしまいまいます。 原因や対処法をご存じの方がいらっしゃいましたらご教示下さい。 一括でコンパイルすると問題なし bash-3.1$ g++ -Wl,--enable-auto-import main.cpp point.cpp -lstdc++ 個別にコンパイルしようとした場合 bash-3.1$ g++ -Wl,--enable-auto-import -o main.o main.cpp C:\DOCUME~1\user\LOCALS~1\Temp\ccZrVmLp.o:main.cpp:(.text+0x16): undefined reference to `Point::Point()' C:\DOCUME~1\user\LOCALS~1\Temp\ccZrVmLp.o:main.cpp:(.text+0x32): undefined reference to `Point::Point(int, int)' C:\DOCUME~1\user\LOCALS~1\Temp\ccZrVmLp.o:main.cpp:(.text+0x3e): undefined reference to `Point::println()' C:\DOCUME~1\user\LOCALS~1\Temp\ccZrVmLp.o:main.cpp:(.text+0x4a): undefined reference to `Point::println()' collect2: ld returned 1 exit status ※ -Wl,--enable-auto-importは、他の警告を消すために入れました、無くても質問の問題に変化はありませんでした。 サンプルソース ---main.cpp--- #include<iostream> #include "point.h" using namespace std; int main(){ Point p1,p2(4,5); p1.println(); p2.println(); return 0; } ----------- ---point.h--- class Point { private: int x, y; static int count; public: Point(); Point( int, int ); void set( int, int ); void println(); }; ------------- ---point.cpp--- #include<iostream> #include"point.h" using namespace std; int Point::count; Point::Point(){ this->x = this->y = 0; ++count; } Point::Point(int ax, int ay){ this->x = ax; this->y = ay; ++count; } void Point::set( int ax, int ay ){ this->x = ax; this->y = ay; } void Point::println(){ cout << "Point(" << x << "," << y << ")" << endl; } ----------- bash-3.1$ g++ -v Using built-in specs. COLLECT_GCC=D:\MinGW\bin\g++.exe COLLECT_LTO_WRAPPER=d:/mingw/bin/../libexec/gcc/mingw32/4.5.0/lto-wrapper.exe Target: mingw32 Configured with: ../gcc-4.5.0/configure --enable-languages=c,c++,ada,fortran,obj c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgo mp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-r untime-libs --disable-werror --build=mingw32 --pref

  • 分割ファイルでstatic変数はどのようにすれば良いのでしょうか?

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