C++ 中线程所做的更改

Posted

技术标签:

【中文标题】C++ 中线程所做的更改【英文标题】:Changes made by threads in C++ 【发布时间】:2015-07-24 12:46:01 【问题描述】:

我正在尝试模拟餐饮哲学家的问题,但无法将其可视化。当线程从 Waiting() 移动到 Eating() 再到 Thinking() 时,它会更改一个名为 state 的变量来表示这一点。但是在我的主线程中,它永远不会看到状态变量的变化。绘制时调用状态返回函数来改变哲学家的颜色。

有什么帮助吗?

下面是一些代码: 状态变化

void Philosopher::Eat()

    state_ = EATING;
    Sleep(500);

返回函数

Philosopher::_state Philosopher::ReturnState()

    return state_;

返回函数的调用

Philosopher::_state current_state_;
    current_state_ = philosopher_[i].ReturnState();

    switch (current_state_)
    
        case Philosopher::PICKING:
        
            glColor3f(1, 0, 0);
            break;
        

        case Philosopher::EATING:
        
            glColor3f(0, 1, 0);
            break;
        

        case Philosopher::THINKING:
        
            glColor3f(0, 0, 1);
            break;
        
    

【问题讨论】:

可能是因为您观察的变量与您正在修改的变量不同。 SSCCE 请。 我不确定您使用的是什么多线程标准(C++11?POSIX pthreads?),但它们中的大多数禁止在一个线程中访问一个对象,而它正在或可能是,在另一个线程中修改。据推测,您使用的标准提供了同步访问共享状态的工具——互斥锁、原子,等等——使用它们。 【参考方案1】:

如果没有同步,尝试从多个线程访问一个变量是未定义行为。添加互斥锁。

【讨论】:

【参考方案2】:

因为这是我能找到的唯一问题:

有什么帮助吗?

这个问题现在已经 6 个月了,我想我会展示如何去做。实际上这里有 四种 方法(在 C++ 中):

Dining Philosophers Rebooted

简单的答案是创建一个std::mutex 数组,它代表每个哲学家之间的叉子,并使用std::lock 将它们锁定(用于进食),如下所示:

std::unique_lock<std::mutex> left (mutexes[i], std::defer_lock);
std::unique_lock<std::mutex> right(mutexes[j], std::defer_lock);
std::lock(left, right);

如果您这样做,并且您发现您的代码花费大量时间旋转,请向您的 std::lib 供应商写一份错误报告并将他们指向本文。他们会认出来的。

或者,如果您愿意,只需从论文中复制四个 ::lock 实现之一(无论哪个最适合您)并使用它。

【讨论】:

以上是关于C++ 中线程所做的更改的主要内容,如果未能解决你的问题,请参考以下文章

如何撤消对 Python 2D 类实例数组所做的更改,例如在 C++ 中

如何使用 Core Data 有效地保存 UI/主线程中所做的更改?

对对象成员、对象内部、向量内部所做的更改不会在方法结束后继续存在。 C++

在连续的 java CompletionStages 之间对共享上下文对象所做的最新更改对于执行 lambda 的每个线程是不是始终可见

绕过/更改“您所做的更改可能无法保存”提示

在 Chrome Devtools 中检测和观察对样式表所做的更改