通过引用传递对象和多线程
Passing object by reference and Multithreading
我有一个小问题,想知道是否有人可以提供帮助。我试图以最简单的方式展示我的问题。我试图通过引用多个线程来传递一个对象。每个线程调用"doSomething",它是属于对象"Example"的成员函数。 "doSomething" 函数应该递增计数器。我的 gcc 版本是 4.4.7
题目:
为什么变量 "counter" 的值没有递增,尽管我通过引用将对象传递给线程函数。
代码:
#include <iostream>
#include <thread>
class Exmaple {
private:
int counter;
public:
Exmaple() {
counter = 0;
}
void doSomthing(){
counter++;
}
void print() {
std::cout << "value from A: " << counter << std::endl;
}
};
// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}
int main()
{
Exmaple b;
while (true) {
std::thread t1(thread_task, b);
t1.join();
}
return 0;
}
输出:
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
while (true) {
std::thread t1(thread_task, b);
t1.join();
}
这里有两件事你需要知道:
- 使用
std::ref
传递引用。
- 无限循环是 C++ 中的未定义行为;
下面的工作示例:
#include <iostream>
#include <thread>
class Exmaple {
private:
int counter;
public:
Exmaple() {
counter = 0;
}
void doSomthing(){
counter++;
}
void print() {
std::cout << "value from A: " << counter << std::endl;
}
};
// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}
int main()
{
Exmaple b;
for(int i =0; i < 10; i++) {
std::thread t1(thread_task, std::ref(b));
t1.join();
}
return 0;
}
输出:
value from A: 1
value from A: 2
value from A: 3
value from A: 4
value from A: 5
value from A: 6
value from A: 7
value from A: 8
value from A: 9
value from A: 10
看到它Live。
尽管更进一步你还应该考虑数据竞争
我对多线程不是很熟悉,但是您将 b
按值传递给线程,而不是按引用。 b
的值然后通过引用传递给 thread_task
,因此值始终为 1。
根据 the documentation,您必须像这样编写线程才能通过引用传递对象:
std::thread t1(thread_task, std::ref(b));
请注意,在 std::thread t1(thread_task, b)
中,您将 b
按值传递给 std::thread
的构造函数(因为您在这里调用构造函数,而不是直接调用 thread_task
)。解决方案可能是用 std::ref
对象包装 b
,或者更改代码以传递指针:
void thread_task(Exmaple* o) {
o->doSomthing();
o->print();
}
int main()
{
Exmaple b;
while (true) {
std::thread t1(thread_task, &b);
t1.join();
}
return 0;
}
我有一个小问题,想知道是否有人可以提供帮助。我试图以最简单的方式展示我的问题。我试图通过引用多个线程来传递一个对象。每个线程调用"doSomething",它是属于对象"Example"的成员函数。 "doSomething" 函数应该递增计数器。我的 gcc 版本是 4.4.7
题目:
为什么变量 "counter" 的值没有递增,尽管我通过引用将对象传递给线程函数。
代码:
#include <iostream>
#include <thread>
class Exmaple {
private:
int counter;
public:
Exmaple() {
counter = 0;
}
void doSomthing(){
counter++;
}
void print() {
std::cout << "value from A: " << counter << std::endl;
}
};
// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}
int main()
{
Exmaple b;
while (true) {
std::thread t1(thread_task, b);
t1.join();
}
return 0;
}
输出:
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
while (true) {
std::thread t1(thread_task, b);
t1.join();
}
这里有两件事你需要知道:
- 使用
std::ref
传递引用。 - 无限循环是 C++ 中的未定义行为;
下面的工作示例:
#include <iostream>
#include <thread>
class Exmaple {
private:
int counter;
public:
Exmaple() {
counter = 0;
}
void doSomthing(){
counter++;
}
void print() {
std::cout << "value from A: " << counter << std::endl;
}
};
// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}
int main()
{
Exmaple b;
for(int i =0; i < 10; i++) {
std::thread t1(thread_task, std::ref(b));
t1.join();
}
return 0;
}
输出:
value from A: 1
value from A: 2
value from A: 3
value from A: 4
value from A: 5
value from A: 6
value from A: 7
value from A: 8
value from A: 9
value from A: 10
看到它Live。
尽管更进一步你还应该考虑数据竞争
我对多线程不是很熟悉,但是您将 b
按值传递给线程,而不是按引用。 b
的值然后通过引用传递给 thread_task
,因此值始终为 1。
根据 the documentation,您必须像这样编写线程才能通过引用传递对象:
std::thread t1(thread_task, std::ref(b));
请注意,在 std::thread t1(thread_task, b)
中,您将 b
按值传递给 std::thread
的构造函数(因为您在这里调用构造函数,而不是直接调用 thread_task
)。解决方案可能是用 std::ref
对象包装 b
,或者更改代码以传递指针:
void thread_task(Exmaple* o) {
o->doSomthing();
o->print();
}
int main()
{
Exmaple b;
while (true) {
std::thread t1(thread_task, &b);
t1.join();
}
return 0;
}