utopia9527 commented on issue #2736:
URL: https://github.com/apache/brpc/issues/2736#issuecomment-2286450670

   > 可以用gdb看看worker线程都卡在哪
   都卡在了 bthread 池子的加锁处。 当把锁和条件变量都换成 std 之后不会发生这种问题。 有如下怀疑死锁的原因,辛苦大佬帮忙看看:
   bthread 池子中,往公共队列读写都会加bthread 锁。 有没有可能 同一个worker 
调度了多个池子中的bthread,多次加锁,导致死锁的发生。
   
   
   调试信息
   ```
   #0  0x00007f2309b6952d in syscall () from /lib64/libc.so.6
   #1  0x00007f230a491841 in 
std::__atomic_futex_unsigned_base::_M_futex_wait_until(unsigned int*, unsigned 
int, bool, std::chrono::duration<long, std::ratio<1l, 1l> >, 
std::chrono::duration<long, std::ratio<1l, 1000000000l> >) () from 
/lib64/libstdc++.so.6
   #2  0x00000000004be95e in 
std::__atomic_futex_unsigned<2147483648u>::_M_load_and_test_until 
(this=0x7f22d05cb020, __assumed=0, __operand=1, __equal=true, 
__mo=std::memory_order_acquire, __has_timeout=false, __s=..., __ns=...) at 
/usr/include/c++/8/bits/atomic_futex.h:102
   #3  0x00000000004aee85 in 
std::__atomic_futex_unsigned<2147483648u>::_M_load_and_test 
(this=0x7f22d05cb020, __assumed=0, __operand=1, __equal=true, 
__mo=std::memory_order_acquire) at /usr/include/c++/8/bits/atomic_futex.h:122
   #4  0x000000000048f2c1 in 
std::__atomic_futex_unsigned<2147483648u>::_M_load_when_equal 
(__mo=std::memory_order_acquire, __val=1, this=0x7f22d05cb020) at 
/usr/include/c++/8/bits/atomic_futex.h:162
   #5  std::__future_base::_State_baseV2::wait (this=0x7f22d05cb010) at 
/usr/include/c++/8/future:337
   #6  0x00000000005a3577 in 
std::__basic_future<std::vector<std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, 
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > > >::_M_get_result (this=0x7f22d0028b80) at 
/usr/include/c++/8/future:717
   #7  0x00000000005a272a in 
std::future<std::vector<std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, 
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > > >::get (this=0x7f22d0028b80) at 
/usr/include/c++/8/future:796
   ```
   
   代码
   ```
   // 往池子里加任务
   template <class F, class... Args>
   auto BThreadPool::enqueue(F&& f, Args&&... args)
       -> std::future<typename std::invoke_result<F, Args...>::type> {
     using return_type = typename std::invoke_result<F, Args...>::type;
     auto task = std::make_shared<std::packaged_task<return_type()>>(
         std::bind(std::forward<F>(f), std::forward<Args>(args)...));
   
     std::future<return_type> res = task->get_future();
     {
       std::lock_guard<bthread_mutex_t> lock(queue_mutex_);
       if (stop_) throw std::runtime_error("enqueue on stop_ped ThreadPool");
       tasks.emplace([task]() { (*task)(); });
     }
     bthread_cond_signal(&condition_);
     return res;
   }
   
   // 从池子取出任务
   void* BThreadPool::TaskFunction(void* args) {
     auto* tp = reinterpret_cast<BThreadPool*>(args);
     while (true) {
       std::function<void()> task;
       {
         // Already specialize "std::lock_guard" and "std::unique_lock" for
         // bthread_mutex_t
         std::lock_guard<bthread_mutex_t> lock(tp->queue_mutex_);
         while (tp->tasks.empty()) {
           if (tp->stop_) break;
           bthread_cond_wait(&tp->condition_, &tp->queue_mutex_);
         }
         if (tp->stop_ && tp->tasks.empty()) {
           return nullptr;
         }
         task = std::move(tp->tasks.front());
         tp->tasks.pop();
       }
       task();
     }
   }
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org
For additional commands, e-mail: dev-h...@brpc.apache.org

Reply via email to