线程当代变量访问和同步机制
我想了解以下代码是否正确
#include <iostream>
#include <boost/thread/thread.hpp>
#include <vector>
using namespace std;
using namespace boost;
class background_task
{
private:
std::vector<int> numbers;
public:
background_task()
{
i=0;
numbers.assign(6000,0);
}
void someLongComputation()
{
while (++i<200)
{
//boost::mutex::scoped_lock(formutex);
// cout << "Thread inside: i= " << this->i << endl;
numbers.at(0)=i;
cout << "Thread inside numbers= " << numbers.at(0) << endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
}
std::vector<int>& getNumbers()
{
return numbers;
}
int i;
};
background_task f;
void valuePicker()
{
int j=0;
while ( (j++) < 20 )
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
cerr << "First number= " << f.getNumbers().at(0) << endl;
}
}
int main(void)
{
boost::thread comp(boost::bind(&background_task::someLongComputation, &f));
boost::thread value(valuePicker);
comp.join();
return 0;
}
此代码应该启动两个线程:一个线程进行 someLongComputation (我添加了一个计时器休眠程序来模拟实际上非常短的 loooong 计算),另一个线程以不同的频率访问数据包含在计算线程中。
我现在想知道这种方法是否正确,因为在我看来不需要互斥体,我会问你如何使这段代码更加线程安全和正确,因为我想我错过了一些东西......
是吗?传递非常量引用是正确的还是使其成为常量应该更安全? 创建的数据永远不能写入,只能读取...
谢谢!我希望通过这个线程最终解决我的初学者对多线程事物的疑虑......
I want to understand if the following code is correct
#include <iostream>
#include <boost/thread/thread.hpp>
#include <vector>
using namespace std;
using namespace boost;
class background_task
{
private:
std::vector<int> numbers;
public:
background_task()
{
i=0;
numbers.assign(6000,0);
}
void someLongComputation()
{
while (++i<200)
{
//boost::mutex::scoped_lock(formutex);
// cout << "Thread inside: i= " << this->i << endl;
numbers.at(0)=i;
cout << "Thread inside numbers= " << numbers.at(0) << endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
}
std::vector<int>& getNumbers()
{
return numbers;
}
int i;
};
background_task f;
void valuePicker()
{
int j=0;
while ( (j++) < 20 )
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
cerr << "First number= " << f.getNumbers().at(0) << endl;
}
}
int main(void)
{
boost::thread comp(boost::bind(&background_task::someLongComputation, &f));
boost::thread value(valuePicker);
comp.join();
return 0;
}
This code should start two thread: one that makes someLongComputation (I added a timer sleeper to simulate the loooong computations which in fact are very short) and another thread which accesses at a different frequency to data contained in the computation thread.
I'm wondering now if this approach is correct, because it seems to me no mutexes are required, I would ask you how to make this code more thread-safe and correct, because I suppose I'm missing something...
Is it correct to pass a non-const reference or should be more safe to make it const?
Data created should never be written, only read...
Thanks! I hope with this thread to finally fix my beginners doubts on multithreading things...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
读取和写入共享数组
numbers
不是线程安全的。如果此代码实际上成功运行,您插入的人工睡眠可能会掩盖问题。您需要对
numbers
向量进行适当的保护,考虑到具体示例,这是非常困难的,因为您通过公共函数getNumbers()
将此向量公开给客户端。这样做意味着您无法控制background_task
的客户端实际与数据交互的方式。我会添加一个 boost::mutex (正如您已经在长计算函数中注释掉的那样),并将其锁定在长计算函数中(仅在访问数组时以保持锁定的范围)小的)。我还将删除 getNumbers() 函数并将其替换为从数组中特定索引处获取值的函数,例如 int getNumberAt(size_t idx); 并将
boost::mutex
也锁定在那里。Reading and writing to the shared array
numbers
is not thread safe. The artificialsleep
that you have inserted are likely masking the issue if this code is actually running successfully.You need to have proper protection around the
numbers
vector, which is very difficult given the exact example because you expose this vector to clients through the public functiongetNumbers()
. Doing so means you cannot necessarily control how clients of thebackground_task
actually interact with the data.I would add a
boost::mutex
(as you have already commented out in the long computation function), and lock it in the long computation function (only when accessing the array to keep the scope of the lock small). I would also remove thegetNumbers()
function and replace it with a function to get a value from the array at a specific index, such asint getNumberAt(size_t idx);
and lock theboost::mutex
there as well.