#include #include #include #include #include #include #include #include #include #include #include struct queries { std::vector all_queries; queries() { for (int tbl= 1; tbl <= 2; tbl++) { std::string tbl_name("t"); tbl_name+= std::to_string(tbl); all_queries.push_back(std::string("DROP TABLE ") + tbl_name); all_queries.push_back(std::string("CREATE TABLE ") + tbl_name + " (i int)"); for (int i= 0; i < 23; i++) { all_queries.push_back(std::string("INSERT INTO ") + tbl_name + std::string(" VALUES(") + std::to_string(i) + ")"); } all_queries.push_back(std::string("SELECT * FROM ") + tbl_name); } } const char *random() { return all_queries[rand() % all_queries.size()].c_str(); } }; static queries my_queries; static std::atomic thread_count; static std::atomic query_counter; std::atomic_bool stop; std::atomic_bool go; std::mutex mutex; std::condition_variable cond_var; void *thread_proc(void *param) { thread_count++; std::unique_lock lk(mutex); while (!go) cond_var.wait(lk); lk.unlock(); MYSQL *mysql= (MYSQL *) param; while (!stop) { mysql_query(mysql, my_queries.random()); MYSQL_RES *res= mysql_use_result(mysql); mysql_free_result(res); while (mysql_next_result(mysql) == 0) { } query_counter++; } thread_count--; return nullptr; } int main(int argc, char **argv) { MY_INIT(argv[0]); int num_connections= 10000; int seconds= 120; if (argc > 1) num_connections= atoi(argv[1]); if (argc > 2) seconds= atoi(argv[2]); MY_INIT(argv[0]); printf("test : %d connections, %d seconds\n", num_connections, seconds); void **connections= new void *[num_connections]; pthread_t *threads= new pthread_t[num_connections]; printf("connecting\n"); for (int i= 0; i < num_connections; i++) { MYSQL *c= mysql_init(nullptr); if (!mysql_real_connect(c, IF_WIN(".", "localhost"), "root", "", "test", 3306, NULL, 0)) { fprintf(stderr, "Failed to connect to database (connection %d): Error: %s\n", i, mysql_error(c)); return 1; } connections[i]= c; } printf("creating threads\n"); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 64 * 1024); for (int i= 0; i < num_connections; i++) { if (pthread_create(&threads[i], &attr, thread_proc, connections[i])) { fprintf(stderr, "Failed to create thread %d: Error: %s\n", i, mysql_error((MYSQL *) connections[i])); return 1; } } printf("Waiting for threads to become ready\n"); while (thread_count != num_connections) std::this_thread::sleep_for(std::chrono::seconds(1)); printf("Done\n"); mutex.lock(); go= true; cond_var.notify_all(); mutex.unlock(); unsigned long long old_counter= 0; int i= 0; for (i= 0; i < seconds; i++) { std::this_thread::sleep_for(std::chrono::seconds(1)); printf("%d: qps=%lld\n", i, (long long) (query_counter - old_counter)); old_counter= query_counter; } stop= true; printf("Waiting for threads to shutdown\n"); for (; thread_count; i++) { std::this_thread::sleep_for(std::chrono::seconds(1)); printf("%d: qps=%lld\n", i, (long long) (query_counter - old_counter)); old_counter= query_counter; seconds++; } printf("queries=%lld, time=%d seconds, throughput=%f\n", query_counter.load(), i, (double) query_counter / i); for (int i= 0; i < num_connections; i++) { mysql_close((MYSQL *) connections[i]); } delete[] connections; return 0; }