Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[coro_rpc] [async_simple] coro_rpc配合ConditionVariable使用出错 #881

Open
ptbxzrt opened this issue Jan 14, 2025 · 8 comments
Open

Comments

@ptbxzrt
Copy link

ptbxzrt commented Jan 14, 2025

最小复现代码如下所示。
coro_rpc配合ConditionVariable使用,程序无法正常退出,用gdb的bt命令查看调用栈,发现调用栈在无限递归。
不知道是不是我的使用方法不对,请求帮助,非常感谢!!!!

#include "async_simple/coro/ConditionVariable.h"
#include "async_simple/coro/Lazy.h"
#include "async_simple/coro/SpinLock.h"
#include "async_simple/coro/SyncAwait.h"
#include "ylt/coro_rpc/impl/coro_rpc_client.hpp"
#include "ylt/coro_rpc/impl/default_config/coro_rpc_config.hpp"
#include <chrono>
#include <thread>

[[nodiscard]] inline std::pair<std::string, int>
splitIPAndPort(std::string fullAddress) {
  std::string ip, port;
  std::size_t colon = fullAddress.find(':');

  assert(colon != std::string::npos);
  ip = fullAddress.substr(0, colon);
  port = fullAddress.substr(colon + 1);

  return {ip, std::stoi(port)};
}

class Server1 {
public:
  coro_rpc::coro_rpc_server rpcServer_;

  async_simple::coro::SpinLock lock_;
  async_simple::coro::ConditionVariable<async_simple::coro::SpinLock> cv_;
  int num_ = 0;

  Server1() : rpcServer_(1, "0.0.0.0:9001") {
    rpcServer_.register_handler<&Server1::addOne>(this);
    rpcServer_.register_handler<&Server1::check>(this);

    rpcServer_.async_start();
  }

  async_simple::coro::Lazy<void> addOne() {
    co_await lock_.coScopedLock();
    num_++;
  }

  async_simple::coro::Lazy<void> check() {
    co_await lock_.coScopedLock();
    co_await cv_.wait(lock_, [this]() { return num_ == 2; });
  }

  async_simple::coro::Lazy<void> work() {
    std::this_thread::sleep_for(std::chrono::seconds(3));
    co_await lock_.coScopedLock();
    num_++;
    cv_.notifyAll();
  }
};

class Server2 {
public:
  coro_rpc::coro_rpc_server rpcServer_;

  Server2() : rpcServer_(1, "0.0.0.0:9002") { rpcServer_.async_start(); }

  async_simple::coro::Lazy<void> work() {
    coro_rpc::coro_rpc_client rpcClient{};
    auto ec = co_await rpcClient.connect(
        splitIPAndPort("0.0.0.0:9001").first,
        std::to_string(splitIPAndPort("0.0.0.0:9001").second));
    if (ec) {
      ELOG_ERROR << ec.message();
      std::terminate();
    }

    auto resp = co_await rpcClient.call<&Server1::addOne>();
    if (!resp) {
      ec = resp.error().code;
      ELOG_ERROR << ec.message();
      std::terminate();
    }

    resp = co_await rpcClient.call<&Server1::check>();
    if (!resp) {
      ec = resp.error().code;
      ELOG_ERROR << ec.message();
      std::terminate();
    }

    resp = co_await rpcClient.call<&Server1::addOne>();
    if (!resp) {
      ec = resp.error().code;
      ELOG_ERROR << ec.message();
      std::terminate();
    }
  }
};

int main() {
  Server1 server1;
  Server2 server2;

  auto th1 =
      std::thread([&]() { async_simple::coro::syncAwait(server1.work()); });

  auto th2 =
      std::thread([&]() { async_simple::coro::syncAwait(server2.work()); });

  th1.join();
  th2.join();

  return 0;
}

从下面这个图可以看到,函数调用栈在无限递归。
Image

@ptbxzrt ptbxzrt changed the title coro_rpc配合ConditionVariable使用出错 [coro_rpc] [async_simple] coro_rpc配合ConditionVariable使用出错 Jan 14, 2025
@poor-circle
Copy link
Collaborator

poor-circle commented Jan 16, 2025

抱歉,这是一个已知问题。和 #847 相同。

@poor-circle
Copy link
Collaborator

poor-circle commented Jan 16, 2025

原因在于目前rpc server的调度器总是调用dispatch立即执行任务,而不是post将任务加入到队列末尾,导致协程栈在你这种争抢锁的情况下出现类似尾递归的现象,导致栈不断增长。

最近几天我们会修复这个问题

@ptbxzrt
Copy link
Author

ptbxzrt commented Jan 16, 2025

原因在于目前rpc server的调度器总是调用dispatch立即执行任务,而不是post将任务加入到队列末尾,导致协程栈在你这种争抢锁的情况下出现类似尾递归的现象,导致栈不断增长。

最近几天我们会修复这个问题

明白,辛苦了!

@poor-circle
Copy link
Collaborator

你可以看下 #882 是否修复了问题

@ptbxzrt
Copy link
Author

ptbxzrt commented Jan 16, 2025

你可以看下 #882 是否修复了问题

似乎还是不太正常欸。

Image

@poor-circle
Copy link
Collaborator

poor-circle commented Jan 16, 2025

你用的是什么编译器呢,包括版本

@ptbxzrt
Copy link
Author

ptbxzrt commented Jan 16, 2025

你用的是什么编译器呢,包括版本

clang 17.0.4

Image

Image

@ptbxzrt
Copy link
Author

ptbxzrt commented Jan 16, 2025

你用的是什么编译器呢,包括版本

clang 17.0.4

Image

Image

我换成gcc 13.1.0,也是这样。

Image

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants