标签:ati index get include size 函数 default 服务 linux
陈硕的《Linux多线程服务端编程:使用muduo C++网络库》中2.2一节中写了一个简单的容量无限的BlockingQueue,其中出队函数enqueue()中,每次添加元素都会调用pthread_cond_signal(封装成了Condition::notify()).然后提了一个问题,如果改成只在queue.size()从0变成1的时候才调用Conditon::notify()会如何.
根据C++11写了个,BlockingQueue的实现放在了这里,test的实现放在了这里
test具体就是1个生产者2个消费者
多次测试发现有很小概率出现了
gdb跟进用thread apply all bt得出了两个消费者
Thread 4 (Thread 0x7ffff5fd0700 (LWP 9076)):
#0 0x00007ffff7bcaf1c in __lll_lock_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007ffff7bc6649 in _L_lock_909 () from /lib/x86_64-linux-gnu/libpthread.so.0
#2 0x00007ffff7bc6470 in pthread_mutex_lock () from /lib/x86_64-linux-gnu/libpthread.so.0
#3 0x00000000004099c3 in __gthread_mutex_lock (__mutex=0x612348 <queue>) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:748
#4 0x000000000040ae95 in std::mutex::lock (this=0x612348 <queue>) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/mutex:134
#5 0x000000000040ae6c in std::unique_lock<std::mutex>::lock (this=0x7ffff5fcfe08) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/mutex:511
#6 0x000000000040acfb in std::unique_lock<std::mutex>::unique_lock (this=0x7ffff5fcfe08, __m=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/mutex:443
#7 0x0000000000409c7e in BlockQueue::BlockQueue<int>::dequeue (this=0x612348 <queue>) at /home/hr/code/somecode/test/../BlockQueue/BlockQueue.h:53
#8 0x00000000004097b7 in test_pop () at /home/hr/code/somecode/test/testStarvation.cc:26
#9 0x000000000040df7f in std::_Bind_simple<int (*())()>::_M_invoke<>(std::_Index_tuple<>) (this=0x613590) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1731
#10 0x000000000040df55 in std::_Bind_simple<int (*())()>::operator()() (this=0x613590) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1720
#11 0x000000000040ddd9 in std::thread::_Impl<std::_Bind_simple<int (*())()> >::_M_run() (this=0x613578) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:115
#12 0x00007ffff7969a60 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#13 0x00007ffff7bc4184 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#14 0x00007ffff70d0ffd in clone () from /lib/x86_64-linux-gnu/libc.so.6
Thread 3 (Thread 0x7ffff67d1700 (LWP 9075)):
#0 0x00007ffff7bcbb9d in nanosleep () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x000000000040b76e in std::this_thread::sleep_for<long, std::ratio<1l, 1l> > (__rtime=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:279
#2 0x0000000000409d3a in BlockQueue::BlockQueue<int>::dequeue (this=0x612348 <queue>) at /home/hr/code/somecode/test/../BlockQueue/BlockQueue.h:63
#3 0x00000000004097b7 in test_pop () at /home/hr/code/somecode/test/testStarvation.cc:26
#4 0x000000000040df7f in std::_Bind_simple<int (*())()>::_M_invoke<>(std::_Index_tuple<>) (this=0x613420) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1731
#5 0x000000000040df55 in std::_Bind_simple<int (*())()>::operator()() (this=0x613420) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1720
#6 0x000000000040ddd9 in std::thread::_Impl<std::_Bind_simple<int (*())()> >::_M_run() (this=0x613408) at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:115
#7 0x00007ffff7969a60 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x00007ffff7bc4184 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#9 0x00007ffff70d0ffd in clone () from /lib/x86_64-linux-gnu/libc.so.6
而gdb的p queue.queue_.size()则得出了
[Thread 0x7ffff67d1700 (LWP 9075) exited]
$1 = 2
可见消费者生产的2个线程并未被消费,因为在第一条插入之后触发0到1的转变,触发notify,但是由于接下来的pop和第二此push的顺序不能确定,如果是pop晚于了push而第二次锁lock的是push而非pop,那么就产生starvation
标签:ati index get include size 函数 default 服务 linux
原文地址:http://www.cnblogs.com/lovewisdom/p/7819332.html