GitHub user condy0919 added a comment to the discussion: EventDispatcher 会自动 
stop、join,为什么 brpc worker 不会自动 stop、join 呢?

今天我又大致看了一下这个问题,针对我所遇到的简单场景,下面这种解法是可以的。

我遇到的场景:

客户端发送包较大,不能一次性写完,会产生 KeepWrite bthread. 但是在客户端退出时,KeepWrite bthread 仍旧存在,之后再遇到 
DoWrite 返回 EAGAIN 它就会调用 `epoll_ctl(... MOD..)` 了。

```diff
diff --git a/src/brpc/event_dispatcher.cpp b/src/brpc/event_dispatcher.cpp
index d1b66983..4f683141 100644
--- a/src/brpc/event_dispatcher.cpp
+++ b/src/brpc/event_dispatcher.cpp
@@ -23,6 +23,7 @@
 #include "butil/third_party/murmurhash3/murmurhash3.h"// fmix32
 #include "bvar/latency_recorder.h"                    // bvar::LatencyRecorder
 #include "bthread/bthread.h"                          // 
bthread_start_background
+#include "bthread/unstable.h"
 #include "brpc/event_dispatcher.h"
 #if BRPC_WITH_URMA
 #include "ubsocket.h"
@@ -73,6 +74,7 @@ void InitializeGlobalDispatchers() {
     }
     // This atexit is will be run before g_task_control.stop() because above
     // Start() initializes g_task_control by creating bthread (to run 
epoll/kqueue).
+    CHECK_EQ(0, atexit(bthread_stop_world));
     CHECK_EQ(0, atexit(StopAndJoinGlobalDispatchers));
 }
 
diff --git a/src/bthread/task_control.cpp b/src/bthread/task_control.cpp
index 0b34955b..d7cc40ae 100644
--- a/src/bthread/task_control.cpp
+++ b/src/bthread/task_control.cpp
@@ -304,7 +304,7 @@ TaskGroup* TaskControl::choose_one_group(bthread_tag_t tag) 
{
     if (ngroup != 0) {
         return groups[butil::fast_rand_less_than(ngroup)];
     }
-    CHECK(false) << "Impossible: ngroup is 0";
+    //CHECK(false) << "Impossible: ngroup is 0";
     return NULL;
 }
 
diff --git a/src/bthread/task_group.cpp b/src/bthread/task_group.cpp
index 67f029a0..c63cad80 100644
--- a/src/bthread/task_group.cpp
+++ b/src/bthread/task_group.cpp
@@ -920,7 +920,12 @@ static void ready_to_run_from_timer_thread(void* arg) {
     const SleepArgs* e = static_cast<const SleepArgs*>(arg);
     auto g = e->group;
     auto tag = g->tag();
-    g->control()->choose_one_group(tag)->ready_to_run_remote(e->meta);
+    auto c = g->control();
+    if (c) {
+       c->choose_one_group(tag)->ready_to_run_remote(e->meta);
+    } else {
+           LOG(WARNING) << "The TaskControl is destroyed. Unable to run task 
anymore";
+    }
 }
```

确实算不上优雅。`bthread_stop_world` 隐式依赖着 event dispatcher 要先退出,不然随着 EventDispatcher 
sched_to 实际的 epoll 任务会扔到 worker 中,所以不能先调用 `bthread_stop_world` 否则会卡死在 
`pthread_join(.. wrk1)` 中。

另外我还发现了,在退出过程中,似乎仍旧有定时器相关的 bthread 要被扔到 worker 中。

GitHub link: 
https://github.com/apache/brpc/discussions/3378#discussioncomment-17840296

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to