线程当代变量访问和同步机制

发布于 2024-12-02 10:37:59 字数 1580 浏览 1 评论 0原文

我想了解以下代码是否正确

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

友谊不毕业 2024-12-09 10:37:59

读取和写入共享数组 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 artificial sleep 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 function getNumbers(). Doing so means you cannot necessarily control how clients of the background_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 the getNumbers() function and replace it with a function to get a value from the array at a specific index, such as int getNumberAt(size_t idx); and lock the boost::mutex there as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文