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]