-- Table: public.demo -- DROP TABLE public.demo; CREATE TABLE public.demo ( id integer NOT NULL DEFAULT nextval('demo_id_seq'::regclass), name character varying(256), CONSTRAINT demo_pk PRIMARY KEY (id) ) WITH ( OIDS=FALSE ); ALTER TABLE public.demo OWNER TO postgres;
#ifndef PGCONNECTION_H #define PGCONNECTION_H #include <memory> #include <mutex> #include <libpq-fe.h> class PGConnection { public: PGConnection(); std::shared_ptr<PGconn> connection() const; private: void establish_connection(); std::string m_dbhost = "localhost"; int m_dbport = 5432; std::string m_dbname = "demo"; std::string m_dbuser = "postgres"; std::string m_dbpass = "postgres"; std::shared_ptr<PGconn> m_connection; }; #endif //PGCONNECTION_H
#include "pgconnection.h" PGConnection::PGConnection() { m_connection.reset( PQsetdbLogin(m_dbhost.c_str(), std::to_string(m_dbport).c_str(), nullptr, nullptr, m_dbname.c_str(), m_dbuser.c_str(), m_dbpass.c_str()), &PQfinish ); if (PQstatus( m_connection.get() ) != CONNECTION_OK && PQsetnonblocking(m_connection.get(), 1) != 0 ) { throw std::runtime_error( PQerrorMessage( m_connection.get() ) ); } } std::shared_ptr<PGconn> PGConnection::connection() const { return m_connection; }
std :: to_string (m_dbport) .c_str (), nullptr, nullptr, m_dbname.c_str (), m_dbuser.c_str (), m_dbpass.c_str ()), & PQfinish); #include "pgconnection.h" PGConnection::PGConnection() { m_connection.reset( PQsetdbLogin(m_dbhost.c_str(), std::to_string(m_dbport).c_str(), nullptr, nullptr, m_dbname.c_str(), m_dbuser.c_str(), m_dbpass.c_str()), &PQfinish ); if (PQstatus( m_connection.get() ) != CONNECTION_OK && PQsetnonblocking(m_connection.get(), 1) != 0 ) { throw std::runtime_error( PQerrorMessage( m_connection.get() ) ); } } std::shared_ptr<PGconn> PGConnection::connection() const { return m_connection; }
#ifndef PGBACKEND_H #define PGBACKEND_H #include <memory> #include <mutex> #include <string> #include <queue> #include <condition_variable> #include <libpq-fe.h> #include "pgconnection.h" class PGBackend { public: PGBackend(); std::shared_ptr<PGConnection> connection(); void freeConnection(std::shared_ptr<PGConnection>); private: void createPool(); std::mutex m_mutex; std::condition_variable m_condition; std::queue<std::shared_ptr<PGConnection>> m_pool; const int POOL = 10; }; #endif //PGBACKEND_H
#include <iostream> #include <thread> #include <fstream> #include <sstream> #include "pgbackend.h" PGBackend::PGBackend() { createPool(); } void PGBackend::createPool() { std::lock_guard<std::mutex> locker_( m_mutex ); for ( auto i = 0; i< POOL; ++i ){ m_pool.emplace ( std::make_shared<PGConnection>() ); } } std::shared_ptr<PGConnection> PGBackend::connection() { std::unique_lock<std::mutex> lock_( m_mutex ); while ( m_pool.empty() ){ m_condition.wait( lock_ ); } auto conn_ = m_pool.front(); m_pool.pop(); return conn_; } void PGBackend::freeConnection(std::shared_ptr<PGConnection> conn_) { std::unique_lock<std::mutex> lock_( m_mutex ); m_pool.push( conn_ ); lock_.unlock(); m_condition.notify_one(); }
#include <thread> #include <iostream> #include "pgbackend.h" void testConnection(std::shared_ptr<PGBackend> pgbackend) { // auto conn = pgbackend->connection(); std::string demo = "SELECT max(id) FROM demo; " ; PQsendQuery( conn->connection().get(), demo.c_str() ); while ( auto res_ = PQgetResult( conn->connection().get()) ) { if (PQresultStatus(res_) == PGRES_TUPLES_OK && PQntuples(res_)) { auto ID = PQgetvalue (res_ ,0, 0); std::cout<< ID<<std::endl; } if (PQresultStatus(res_) == PGRES_FATAL_ERROR){ std::cout<< PQresultErrorMessage(res_)<<std::endl; } PQclear( res_ ); } // pgbackend->freeConnection(conn); } int main(int argc, char const *argv[]) { auto pgbackend = std::make_shared<PGBackend>(); std::vector<std::shared_ptr<std::thread>> vec; for ( size_t i = 0; i< 50 ; ++i ){ vec.push_back(std::make_shared<std::thread>(std::thread(testConnection, pgbackend))); } for(auto &i : vec) { i.get()->join(); } return 0; }
g++ main.cpp pgbackend.cpp pgconnection.cpp -o pool -std=c++14 -I/usr/include/postgresql/ -lpq -lpthread
Source: https://habr.com/ru/post/322966/