C++/Thrift:TThreadedServer::stop() 是线程安全的吗?
C++/Thrift: Is TThreadedServer::stop() thread-safe?
我想在单独的线程中使用 TTheadedServer
来控制何时 stop/start 它。我的应用程序只需要 1 个控制线程和一个处理线程。我不希望有超过一个客户,因为我正在使用节俭作为中继。 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()
启动服务器,然后等待一段时间,然后停止它。我 运行 使用线程清理器进行此操作,并收到一些线程安全警告。我在这里提到 2:
首先: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
控制器线程安全吗? Thread-sanitizer 似乎并不这么认为,尽管测试程序运行没有问题。
我正在使用 Thrift 0.12.0。
它是线程安全的,但它可能存在在实践中永远不会出现的多线程错误。例如,在 interruptableChildren_
的情况下 - 流程是您可以在主线程中配置它的值,然后它被接受线程读取(TServerSocket::acceptImpl
运行)。理论上,您可以写入和读取不受保护的变量。实际上,在启动服务器后,您永远不会更改它
std::thread t(&ths::TThreadedServer::serve, &server);
行,因此不会发生数据竞争。
我猜 notify()
情况类似。
我想在单独的线程中使用 TTheadedServer
来控制何时 stop/start 它。我的应用程序只需要 1 个控制线程和一个处理线程。我不希望有超过一个客户,因为我正在使用节俭作为中继。 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()
启动服务器,然后等待一段时间,然后停止它。我 运行 使用线程清理器进行此操作,并收到一些线程安全警告。我在这里提到 2:
首先: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
控制器线程安全吗? Thread-sanitizer 似乎并不这么认为,尽管测试程序运行没有问题。
我正在使用 Thrift 0.12.0。
它是线程安全的,但它可能存在在实践中永远不会出现的多线程错误。例如,在 interruptableChildren_
的情况下 - 流程是您可以在主线程中配置它的值,然后它被接受线程读取(TServerSocket::acceptImpl
运行)。理论上,您可以写入和读取不受保护的变量。实际上,在启动服务器后,您永远不会更改它
std::thread t(&ths::TThreadedServer::serve, &server);
行,因此不会发生数据竞争。
我猜 notify()
情况类似。