2009-08-19 46 views
1

在java中我有以下生成的代碼:如何檢索與C++中的線程相關的對象實例?

public class B { 
    public void exec(){ 
     X x = (X) Thread.currentThread(); 
     System.out.println(x.value); 
    } 
} 

public class X extends Thread{ 
    public int value; 

    public X(int x){ 
     value = x; 
    } 
    public void run(){ 
     B b = new B(); 
     b.exec(); 
    } 
} 

new X(4).start(); 

在B exec()方法檢索對應於該當前線程(也是類X的實例)的字段值。

有沒有辦法在C++中模擬相同的行爲?注意:我不想將x作爲參數傳遞給B實例,因爲代碼已生成。

class B { 
public: 
    void exec(); 
}; 

class X { 
public: 
    int value; 
    X(int x) { 
     value = x; 
    } 
    void run() { 
     B * b = new B(); 
     b->exec(); 
    }  
}; 

void B::exec() { 
    std::cout << ??? << std::endl; 
} 

int main() { 
    X * x = new X(3); 
    boost::thread thr(boost::bind(&X::run, x)); 
    thr.join(); 
} 

我不知道如何檢索相關的線程(我知道我沒有之一)的類實例,任何想法?

回答

2

確實,您不能(或不應該)子類boost::thread。你可以使用thread-local storage來自己設置線程的東西。

可以說,你應該對Java代碼使用相同的技術。 Java爲此具有ThreadLocal

4

如果您不想將參數傳遞給B(這將是最乾淨的解決方案),則可以使用線程本地存儲。

儘管看了你的代碼,但你可能會試圖通過嘗試這種嚴格的從1到1的從Java到C++的映射。

在C++中,你幾乎不應該調用new。儘可能在堆棧上分配。 C++中的new明顯容易出錯(沒有垃圾回收),但與Java等託管語言相比,它也非常慢。

函子可以用作功能指針的一個更強大的替代(例如創建線程時),或者只是替換通用的exec()run()函數。取而代之的是將它們命名爲operator(),並且該類可以用作函子。

而在你的構造函數中,你應該儘可能地使用初始化列表。

以下內容將上述建議應用於您的代碼。當然,我向B構造函數傳遞了一個參數。如果這不是一個選項,請改用thread local storage

class B { 
public: 
    explicit B(int value) : value(value) 
    void operator()(); 

private: 
    int value; 
}; 

class X { 
public: 
    int value; 
    X(int x) :value(x) { }// use the initializer list to initialize members 

    void operator()() { 
     B b(value); // allocate B on the stack if possible 
     b(); 
    }  
}; 

void B::operator()() { 
    std::cout << value << std::endl; 
} 

int main() { 
    boost::thread thr(X(3)); 
    thr.join(); 
} 

當然,在這個簡單的例子,你並不真的需要擺在首位兩班。您可以完全刪除X並完成:

class B { 
public: 
    explicit B(int value) : value(value) 
    void operator()(); 

private: 
    int value; 
}; 

void B::operator()() { 
    std::cout << value << std::endl; 
} 

int main() { 
    boost::thread thr(B(3)); 
    thr.join(); 
}