我写这样的节俭服务器:
服务器:
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
shared_ptr<CalculatorHandler> handler(new CalculatorHandler());
shared_ptr<TProcessor> processor(new CalculatorProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(9009));
shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(15);
shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
boost::shared_ptr<TServer> server(new TNonblockingServer(processor, protocolFactory, 9009, threadManager));
server->serve();
处理程序:
class CalculatorHandler : public CalculatorIf {
public:
CalculatorHandler() {}
void monitor(string& _return, const string& hi) {
printf("%s\n", hi.c_str());
_return = hi;
}
}
然后由valgrind运行它来检查数据竞争:
valgrind --tool=helgrind --log-file=helgrind.log ./TutorialServer
和客户端使用10个线程查询monitor();
helgrind报告是:
840 ==30920== Possible data race during read of size 8 at 0x6927FF0 by thread #4
841 ==30920== Locks held: none
842 ==30920== at 0x407FB1: apache::thrift::protocol::TVirtualProtocol<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>, apache::thrift::protocol::TPro
843 ==30920== by 0x417FC4: shared::SharedStruct::write(apache::thrift::protocol::TProtocol*) const (TProtocol.h:463)
844 ==30920== by 0x41627E: shared::SharedService_getStruct_result::write(apache::thrift::protocol::TProtocol*) const (SharedService.cpp:125)
845 ==30920== by 0x416491: shared::SharedServiceProcessor::process_getStruct(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*) (SharedService.cpp
846 ==30920== by 0x415A49: shared::SharedServiceProcessor::dispatchCall(apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, std::string const&, int, void*) (Sh
847 ==30920== by 0x40890D: apache::thrift::TDispatchProcessor::process(boost::shared_ptr<apache::thrift::protocol::TProtocol>, boost::shared_ptr<apache::thrift::protocol::TProtocol>,
848 ==30920== by 0x4EABDBC: apache::thrift::server::TThreadPoolServer::Task::run() (TThreadPoolServer.cpp:68)
849 ==30920== by 0x4E764BE: apache::thrift::concurrency::ThreadManager::Task::run() (ThreadManager.cpp:185)
850 ==30920== by 0x4E79198: apache::thrift::concurrency::ThreadManager::Worker::run() (ThreadManager.cpp:314)
851 ==30920== by 0x4EB2DC5: apache::thrift::concurrency::PthreadThread::threadMain(void*) (PosixThreadFactory.cpp:207)
852 ==30920== by 0x4C2DC3D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
853 ==30920== by 0x50DCE99: start_thread (pthread_create.c:308)
854 ==30920==
855 ==30920== This conflicts with a previous write of size 8 by thread #3
856 ==30920== Locks held: none
857 ==30920== at 0x407770: boost::detail::sp_counted_impl_p<apache::thrift::protocol::TProtocol>::~sp_counted_impl_p() (sp_counted_base_gcc_x86.hpp:114)
858 ==30920== by 0x4EABB86: apache::thrift::server::TThreadPoolServer::Task::~Task() (sp_counted_base_gcc_x86.hpp:159)
859 ==30920== by 0x4E76FD1: apache::thrift::concurrency::ThreadManager::Task::~Task() (sp_counted_base_gcc_x86.hpp:145)
860 ==30920== by 0x4E790BF: apache::thrift::concurrency::ThreadManager::Worker::run() (sp_counted_base_gcc_x86.hpp:145)
861 ==30920== by 0x4EB2DC5: apache::thrift::concurrency::PthreadThread::threadMain(void*) (PosixThreadFactory.cpp:207)
862 ==30920== by 0x4C2DC3D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
863 ==30920== by 0x50DCE99: start_thread (pthread_create.c:308)
864 ==30920== by 0x59092EC: clone (clone.S:112)
865 ==30920==
866 ==30920== Address 0x6927FF0 is 0 bytes inside a block of size 26 alloc'd
867 ==30920== at 0x4C2B377: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
868 ==30920== by 0x53B2138: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.20)
869 ==30920== by 0x53B21B3: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.20)
870 ==30920== by 0x53B27CD: std::string::_M_replace_safe(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.20)
871 ==30920== by 0x40CA92: CalculatorHandler::calculate(int, tutorial::Work const&) (basic_string.h:1121)
872 ==30920== by 0x41061F: tutorial::CalculatorProcessor::process_calculate(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*) (Calculator.cpp:114
873 ==30920== by 0x40DC2A: tutorial::CalculatorProcessor::dispatchCall(apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, std::string const&, int, void*) (Cal
874 ==30920== by 0x40890D: apache::thrift::TDispatchProcessor::process(boost::shared_ptr<apache::thrift::protocol::TProtocol>, boost::shared_ptr<apache::thrift::protocol::TProtocol>,
875 ==30920== by 0x4EABDBC: apache::thrift::server::TThreadPoolServer::Task::run() (TThreadPoolServer.cpp:68)
876 ==30920== by 0x4E764BE: apache::thrift::concurrency::ThreadManager::Task::run() (ThreadManager.cpp:185)
877 ==30920== by 0x4E79198: apache::thrift::concurrency::ThreadManager::Worker::run() (ThreadManager.cpp:314)
878 ==30920== by 0x4EB2DC5: apache::thrift::concurrency::PthreadThread::threadMain(void*) (PosixThreadFactory.cpp:207)
有问题吗? 要么 节俭真正的线程安全?
希望有人帮助我。 感谢。