apollo
apollo copied to clipboard
是否存在死循环
Describe the bug A clear and concise description of what the bug is.
template <typename T>
bool BoundedQueue<T>::Enqueue(const T& element) {
uint64_t new_tail = 0;
uint64_t old_commit = 0;
uint64_t old_tail = tail_.load(std::memory_order_acquire);
do {
new_tail = old_tail + 1;
if (GetIndex(new_tail) == GetIndex(head_.load(std::memory_order_acquire))) {
return false;
}
} while (!tail_.compare_exchange_weak(old_tail, new_tail,
std::memory_order_acq_rel,
这段代码,old_tail值只是进入函数时更新了下,如果当前生产者没有获得可写入的索引,那下一次就可能无法退出循环,有可能等到整个下一次循环!
To Reproduce Steps to reproduce the behavior:
- Go to '...'
- Click on '....'
- Scroll down to '....'
- See error
Expected behavior A clear and concise description of what you expected to happen.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
Smartphone (please complete the following information):
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
Additional context Add any other context about the problem here.
- 当队列为满时,获取不到 index,则返回 false
if (GetIndex(new_tail) == GetIndex(head_.load(std::memory_order_acquire))) {
return false;
}
- 当没有其它线程同时入列时,则获取到 index,这时不用更新 old_tail,但需要更新 tail(即 new_tail)。
- 当同时有其它线程入列且成功时(此时 tail 已在入列成功的线程中被更新),则先更新 old_tail(即 tail + 1),再重新获取 index,直到获取成功或队列满。