"data ready" 标志的同步机制?
Synchronization Mechanism For "data ready" Flag?
考虑以下 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;
}
}
有没有更好的方法来完成这个?我在考虑条件变量,但我需要能够重置标志以确保对 RequestData() 的背靠背调用不会产生相同的数据。
一如既往,在此先感谢您的帮助。
我不知道您的最终目标是什么,但也许使用实际的线程安全队列会简化您的代码。这是一个:
http://www.boost.org/doc/libs/1_53_0/doc/html/boost/lockfree/queue.html
如果标志是您唯一关心的问题,那么您可以尝试使用 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;
}
}
但是,在实际代码中,您将在 'push data' 和 'copy over data' 段代码之间竞争,除非它们单独同步。
考虑以下 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;
}
}
有没有更好的方法来完成这个?我在考虑条件变量,但我需要能够重置标志以确保对 RequestData() 的背靠背调用不会产生相同的数据。
一如既往,在此先感谢您的帮助。
我不知道您的最终目标是什么,但也许使用实际的线程安全队列会简化您的代码。这是一个:
http://www.boost.org/doc/libs/1_53_0/doc/html/boost/lockfree/queue.html
如果标志是您唯一关心的问题,那么您可以尝试使用 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;
}
}
但是,在实际代码中,您将在 'push data' 和 'copy over data' 段代码之间竞争,除非它们单独同步。