Thrift TThreadPoolServer returns "Segmentation fault; core dumped;" 当处理并发 MySQL 数据库请求时

Thrift TThreadPoolServer returns "Segmentation fault; core dumped;" when handle concurrent MySQL database requests

我正在使用 Apache Thrift 和 C++ POCO 库开发一个简单的作业。作业要求我通过创建多个并发线程向 Thrift 发出相同的请求来进行基准测试 TThreadPoolServer.

这是我的客户端代码,我在其中创建了 10 个并发线程,所有线程都向服务器发出相同的 GET 请求(仅从一个用户 D 请求信息):

// define a MyWorker class which inherits Runnable
class MyWorker : public Runnable {
    public:

    MyWorker(int k = -1) : Runnable(), n(k) {
    }

    void run() {
        // create connection
        boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
        boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
        boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
        APIsClient client(protocol);
        try {
            transport->open();
            int res = -1;
            // make the request
            res = client.get("D"); 
            printf("Thread %d, res = %d \n", n, res);
            transport->close();
        } catch (TException te) {
            cout << te.what() << endl;
        }
    }
private:
    int n;
};

void handleBenchmarkTest(const std::string& name, const std::string& value) {
        //TODO!
        const int N = 10;
        MyWorker w[N];
        for (int i = 0; i < N; i++) w[i] = MyWorker(i);
        Thread t[N];
        for (int i = 0; i < N; i++) t[i].start(w[i]);
        for (int i = 0; i < N; i++) t[i].join(); // wait for all threads to end

        cout << endl << "Threads joined" << endl;
    }

我使用 TThreadPoolServer 实现了我的服务器。这是服务器收到 GET 请求时的处理函数:

   // this function make use of POCO::Data   
int getRequest(const std::string& _username) {
            int res = -1;
            Statement select(*mySQLsession);
            std::string match("'" + _username + "'");
            select << "SELECT counter FROM view_count_info WHERE username = " + match + " LIMIT 1;", into(res);
            select.execute();
            return res;
        }

以上是我的全部代码。当我 运行 客户端基准测试应用程序时,这就是 returned:

MySQL // from the try-catch block above
MySQL // from the try-catch block above
Thread 2, res = -1 // expected result
MySQL // from the try-catch block above
Thrift: Fri Jun 26 15:54:05 2015 TSocket::read() recv() <Host: localhost Port: 9090>Connection reset by peer
No more data to read.
THRIFT_ECONNRESET
No more data to read.
No more data to read.
Thrift: Fri Jun 26 15:54:05 2015 TSocket::read() recv() <Host: localhost Port: 9090>Connection reset by peer
THRIFT_ECONNRESET
Thrift: Fri Jun 26 15:54:05 2015 TSocket::read() recv() <Host: localhost Port: 9090>Connection reset by peer
THRIFT_ECONNRESET

Threads joined

在服务器中,结果是:

2015-06-26 08:54:00 : > Server is running
2015-06-26 08:54:05 : handle GET request
D
2015-06-26 08:54:05 : handle GET request
D
2015-06-26 08:54:05 : handle GET request
D
-1
2015-06-26 08:54:05 : handle GET request
2015-06-26 08:54:05 : handle GET request
D
2015-06-26 08:54:05 : handle GET request
D
2015-06-26 08:54:05 : handle GET request
D
D

RUN FINISHED; Segmentation fault; core dumped; real time: 5s; user: 0ms; system: 0ms

我不知道为什么会这样。 还有一件事,当我尝试更改为在服务器端不使用 MySQL 请求时(我只是 return 每个请求的随机整数),应用程序 运行 很好,没有任何错误或警告。 所以我猜这里的问题出在 MySQL 数据库上。如果我一次只发出 1 个请求,它确实有效,但是当有多个并发 GET 请求时出现问题。

感谢@JensG,我发现这里的问题是因为我使用了一个全局变量mySQLsession来处理所有的MySQL数据库请求,导致线程冲突。再次感谢大家!