Synchronization Mechanism For “data ready” Flag?

2019-08-06 03:46发布

问题:

Consider the following pseudo-code in C++:

// somewhere in common code, properly scoped
boost::mutex data_ready_lock;
bool data_ready;

// Thread 1:
void SomeThreadFunc() {
  // ... push data onto a shared data structure that is properly locked
  data_ready_lock.lock();
  data_ready = true;
  data_ready_lock.unlock();
}

// Thread 2:  (actually a function called from the main() thread)
// Returns the number of bytes written to output_data
size_t RequestData(uint8_t* const output_data) {
  data_ready_lock.lock();
  if (data_ready) {
    // reset the flag, so I don't read out the same data twice
    data_ready = false;
    data_ready_lock.unlock();
    // copy over data, etc.
    return kDataSize;
  } else {
    data_ready_lock.unlock();
    return 0;
  }
}

Is there a better way to accomplish this? I was thinking about condition variables, but I need the ability to reset the flag to ensure that back to back calls to RequestData() don't yield the same data.

As always, thanks in advance for the help.

回答1:

If the flag is the only your concern then you might try using atomic.

// somewhere in common code, properly scoped
boost::atomic< bool > data_ready(false); // can be std::atomic and std::memory_order_* below

// Thread 1:
void SomeThreadFunc() {
  // ... push data onto a shared data structure that is properly locked
  data_ready.store(true, boost::memory_order_release);
}

// Thread 2:  (actually a function called from the main() thread)
// Returns the number of bytes written to output_data
size_t RequestData(uint8_t* const output_data) {
  if (data_ready.exchange(false, boost::memory_order_acquire)) {
    // copy over data, etc.
    return kDataSize;
  } else {
    return 0;
  }
}

However, in a real code you will have a race between the 'push data' and 'copy over data' pieces of code, unless they are synchronized separately.



回答2:

I don't know what your end goal is, but maybe using an actual thread-safe queue would simplify your code. Here is one:

http://www.boost.org/doc/libs/1_53_0/doc/html/boost/lockfree/queue.html