代码之家  ›  专栏  ›  技术社区  ›  The Quantum Physicist

C++/Thrift:TThreadedServer::stop()是否线程安全?

  •  1
  • The Quantum Physicist  · 技术社区  · 7 年前

    我想用这个 TTheadedServer 在一个单独的线程中控制何时停止/启动它。我的应用程序只需要一个控制线程和一个处理线程。我不希望有超过一个客户,因为我使用节俭作为中继。 TSimpleServer 不是线程安全的,所以我放弃了这个选项。

    我做了一个简单的例子来检查它是否是线程安全的,并使用了clang的线程消毒剂来确保它是线程安全的。下面是一个例子

    std::shared_ptr<MyHandler> handler = std::make_shared<MyHandler>();
    
    int port = 9090;
    
    th::stdcxx::shared_ptr<th::TProcessor>         processor(new HandlerProcessor(handler));
    th::stdcxx::shared_ptr<tht::TServerTransport>  serverTransport(new tht::TServerSocket(port));
    th::stdcxx::shared_ptr<tht::TTransportFactory> transportFactory(
        new tht::TBufferedTransportFactory());
    th::stdcxx::shared_ptr<thp::TProtocolFactory> protocolFactory(new thp::TBinaryProtocolFactory());
    
    ths::TThreadedServer server(processor, serverTransport, transportFactory, protocolFactory);
    
    // start in another thread
    std::thread          t(&ths::TThreadedServer::serve, &server);
    t.detach();
    
    std::this_thread::sleep_for(std::chrono::seconds(5));
    
    // stop in this thread
    server.stop();
    
    std::this_thread::sleep_for(std::chrono::seconds(5));
    

    serve() 在另一个线程中,然后等待一段时间,并停止它。我用线程消毒剂运行了这个程序,得到了一些线程安全警告。我在这里提到第二点:

    thrift/lib/cpp/src/thrift/transport/TServerSocket.cpp:244

    interruptableChildren_ = enable;
    

    第二: thrift/lib/cpp/src/thrift/transport/TServerSocket.cpp:654 ,网址:

    if (-1 == send(notifySocket, cast_sockopt(&byte), sizeof(int8_t), 0)) {
      GlobalOutput.perror("TServerSocket::notify() send() ", THRIFT_GET_SOCKET_ERROR);
    }
    

    那么我所做的是正确的吗?而且是 TThreadedServer 控制器线程安全?线程消毒剂似乎不这么认为,尽管测试程序工作没有问题。

    我用的是节俭0.12.0。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Roman    7 年前

    它是线程安全的,但它可能有多线程错误,这些错误在实践中永远不会出现。例如,在 interruptableChildren_ -流程是,您可以在主线程中配置它的值,但它由接受线程读取(其中 TServerSocket::acceptImpl 运行)。理论上,您可以从未受保护的变量进行写入和读取。实际上,在使用启动服务器后,您永远不会更改它 std::thread t(&ths::TThreadedServer::serve, &server);

    我猜 notify() 情况类似。