C ++ / Thrift: TThreadedServer :: stop () поточно-ориентирован? - PullRequest
0 голосов
/ 25 декабря 2018

Я бы хотел использовать TTheadedServer в отдельном потоке, чтобы контролировать, когда его останавливать / запускать.Моему приложению требуется только 1 управляющий поток и один поток обработки.Я не ожидаю иметь более одного клиента, так как я использую Thrift в качестве реле.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 контроллер потокобезопасным?Средство очистки потока, кажется, так не считает, хотя тестовая программа работает без проблем.

Я использую Thrift 0.12.0.

1 Ответ

0 голосов
/ 25 декабря 2018

Это потокобезопасный, но он может иметь многопоточные ошибки, которые никогда не проявятся на практике.Например, в случае interruptableChildren_ - поток таков, что вы можете настроить его значение в основном потоке, но затем оно будет прочитано потоком-получателем (где работает TServerSocket::acceptImpl).Теоретически вы пишете и читаете из незащищенной переменной.На практике вы никогда не меняете его после запуска сервера со строкой std::thread t(&ths::TThreadedServer::serve, &server); , поэтому скачки данных не произойдут.

Я предполагаю, что notify() аналогично.

...