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数据库请求,导致线程冲突。再次感谢大家!
我正在使用 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数据库请求,导致线程冲突。再次感谢大家!