一個線程餓死的例子

來源:互聯網
上載者:User

標籤: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

一個線程餓死的例子

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.