如何在C ++中实现Exchanger(Rendezvous Pattern)?

时间:2010-07-09 04:51:12

标签: c++ multithreading boost-thread

在Java中,有一个Exchanger类(http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Exchanger.html)。如何在C ++中实现类似的东西(使用boost)

3 个答案:

答案 0 :(得分:1)

最好的办法是理解implementation in Java itself并尝试使用boost线程类重新实现它。

答案 1 :(得分:0)

好的,这是我第二次尝试清理比赛状况。当多于两个线程尝试使用单个交换器对象时效率低下,但由于这是一个边缘情况,我认为我们可以忍受这样:

#include <boost/thread.hpp>

template <class T>
class exchanger
{
public:
    exchanger()
        : ptr(0),
          state(EMPTY)
    {
    }

    void exchange(T &t)
    {
        boost::unique_lock<boost::mutex> lock(m);

        // If we arrive while an actual exchange has 
        // started but has not finished, keep out of
        // the way.
        while (state == SECOND_ARRIVED)
        {
            cv_overflow.wait(lock);
        }

        assert((state == EMPTY) || (state == FIRST_ARRIVED));

        switch (state)
        {
        case EMPTY:
            assert(!ptr);
            ptr = &t;
            state = FIRST_ARRIVED;
            while (state == FIRST_ARRIVED)
            {
                cv_main.wait(lock);
            }
            assert(state == SECOND_ARRIVED);

            ptr = 0;
            state = EMPTY;

            // Wake up any threads that happened to get
            // the mutex after the other side of the
            // exchanger notified us but before we woke up.
            cv_overflow.notify_all();
            break;

        case FIRST_ARRIVED:
            assert(ptr);
            state = SECOND_ARRIVED;
            using std::swap;
            swap(t, *ptr);
            cv_main.notify_one();
            break;
        }
    }

private:
    boost::mutex m;
    boost::condition_variable cv_main;
    boost::condition_variable cv_overflow;
    T *ptr;

    enum { EMPTY, FIRST_ARRIVED, SECOND_ARRIVED } state;
};

答案 2 :(得分:0)

您应该使用一对屏障来实现交换器,在交换值之前一个用于同步,在交换之后一个用于同步。我在下面的git中用c ++完成了Java兼容的实现,请继续 通过相同的。

https://github.com/anandkulkarnisg/Exchanger?files=1