Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 一旦获得第一个锁,排队等待全局锁的多个线程都应返回true_C++_Multithreading_Boost_Synchronization - Fatal编程技术网

C++ 一旦获得第一个锁,排队等待全局锁的多个线程都应返回true

C++ 一旦获得第一个锁,排队等待全局锁的多个线程都应返回true,c++,multithreading,boost,synchronization,C++,Multithreading,Boost,Synchronization,一个类似的问题是:然而,在这个问题中,一旦获得锁,只有一个线程执行受保护的代码,最终所有线程都将执行该代码 我想做的是执行一次受保护的代码,但是对于当时排队等待方法调用的所有线程,返回true 基本上,受保护的代码是一个全局检查点,它与此时等待的所有线程相关。也就是说,执行N个连续的检查点不会获得超过1个的结果 请注意,在完成检查点时,将有其他对该方法的调用,这些调用本身需要一个新的检查点调用 我相信我要做的是对全局函数的“批处理”同步调用 如何在C++中实现这一点,也许是用Boost?p> 您

一个类似的问题是:然而,在这个问题中,一旦获得锁,只有一个线程执行受保护的代码,最终所有线程都将执行该代码

我想做的是执行一次受保护的代码,但是对于当时排队等待方法调用的所有线程,返回true

基本上,受保护的代码是一个全局检查点,它与此时等待的所有线程相关。也就是说,执行N个连续的检查点不会获得超过1个的结果

请注意,在完成检查点时,将有其他对该方法的调用,这些调用本身需要一个新的检查点调用

我相信我要做的是对全局函数的“批处理”同步调用


如何在C++中实现这一点,也许是用Boost?p> 您似乎在寻找
try\u lock()

给定一些Boost.Thread
Lockable
,调用
Lockable::try_lock()
将返回true,如果此时可以获取锁,则返回false


当线程到达检查点时,让它尝试获取此锁。如果失败,则函数中已存在另一个线程。如果成功,请检查一些
bool
,查看检查点是否已经运行。如果已运行,请释放锁并继续。如果尚未运行,请保持锁定并运行checkpoint函数,然后将checkpoint
bool
设置为true。

您想要的看起来像是由提供的屏障。然而,如果这对您没有帮助,您可以使用条件变量制作一些东西,同样在

中,这里是我将如何做的伪代码。我假设存在一个带有
lock()
unlock()
操作的
mutex

// This forward declaration helps with declaration
// of the "friend" status for the nested class.
class DoItOnce;

class DoItOnce
{
private:
    bool    m_amFirst;
    mutex   m_mutex;
    friend class ::DoItOnce::Op;    
public:
    DoItOnce()
    {
        m_amFirst = true;
        init(m_mutex);
    }
    ~DoItOnce() { destroy(m_mutex); }
    void reset()
    {
        m_mutex.lock();
        m_amFirst = true;
        m_mutex.lock();
    }

    //--------
    // Nested class
    //--------
    class Op {
    public:
        Op(DoItOnce & sync)
            : m_sync(sync)
        {
            m_sync.m_mutex.lock();
            m_amFirst = m_sync.m_amFirst;
            m_sync.m_amFirst = false;
        }
        ~Op() { m_sync.m_mutex.unlock(); }
        bool amFirst() { return m_amFirst; }
    private:
        DoItOnce &  m_sync;
        bool        m_amFirst;
    }; // end of nested class
}; // end of outer class
下面是一个例子来说明它的预期用途。您将实现
doWork()
操作,并让所有线程调用它

class WorkToBeDoneOnce
{
private:
    DoItOnce    m_sync;    
public:
    bool doWork()
    {
        DoItOnce::Op    scopedLock(m_sync);

        if (!scopedLock.amFirst()) {
            // The work has already been done.
            return true;
        }
        ... // Do the work
        return true;
    }
    void resetAmFirstFlag()
    {
        m_sync.reset();
    }
}

如果您对我使用的
DoItOnce::Op
嵌套类感到困惑,那么您可以在我的通用同步策略论文中找到关于此编码习惯用法的解释,该论文有多种格式(HTML、PDF和幻灯片)。

非常有趣。如果对所有N个线程来说,只调用一次全局函数就足够了,并且给出这样的结果:“wait()返回:N个线程中正好有一个将接收到true的返回值,其他线程将接收到false的返回值。”我应该能够将它与一个全局变量组合,该变量由作为响应得到true的线程设置,每个错误线程都在等待吗?同样,这似乎假设了一个固定的N。如果N未知,甚至可能非常低,比如1或2,那又如何呢?经过一些思考,我猜这个障碍不是你想要的。或者,Daupics方法是可以的,只要锁定,您就会返回,或者您需要一个额外的计时器来延迟和分组访问,并使用条件变量分组。您是说在屏障上设置一个看门狗计时器->等待()--屏障填满或者计时器触发函数调用?否,我的意思是一个分组计时器来进行批处理,所以在延迟之后,可能会有5个线程等待。然后,您可以通知1执行,然后通知其他人(广播)返回。您已经看过boosts条件变量了吗?假设try_lock()对某些线程返回false。这意味着该线程需要等待锁,并且无论bool是true还是false,我都不能确定检查点是否针对该线程的状态运行?如果
try\u lock()
为某个线程返回false,则表示该锁已由另一个线程拥有。假设每个检查点都有一个锁,可以安全地假设另一个线程当前正在执行检查点代码,或者已经执行了检查点代码。我是不是误解了你的意思?