Replies: 2 comments 1 reply
|
因为没法优雅且安全地停 worker和消费完所有 bthread,所以 我之前做过优雅退出相关工作,还需要修改TaskControl/TaskGroup,最后的实现不优雅,没法覆盖一些 corner case。#1889 (comment) 有一些讨论。 |
1 reply
|
今天我又大致看了一下这个问题,针对我所遇到的简单场景,下面这种解法是可以的。 我遇到的场景: 客户端发送包较大,不能一次性写完,会产生 KeepWrite bthread. 但是在客户端退出时,KeepWrite bthread 仍旧存在,之后再遇到 DoWrite 返回 EAGAIN 它就会调用 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 要被扔到 worker 中。 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
针对 EventDispatcher 线程,注册了 atexit 函数 StopAndJoinGlobalDispatcher. 那么为什么不针对全局的 TaskControl 也处理一下呢?
我看到了有一个函数
bthread_stop_world就是用来做这个事情的,也可以将它注册进 atexit 的吧。当前没有这样做的原因是啥呢?All reactions