Jeroen T. Vermeulen wrote:
> On Wed, July 11, 2007 01:41, Fei Liu wrote:
>
>
>> I just realized my problem was using transactor model within a
>> multi-thread environment...Is there any tutorial or example code using
>> pqxx in a multi-thread application environment? Thanks
>>
>
> Not yet, and we still need to do a lot of work to include locks. Right
> now libpqxx itself doesn't do any locking.
>
> There are several ways to ensure thread safety for your use of libpqxx:
>
> 1. Do all your database work in a single thread. It saves time on
> establishing multiple connections, too.
>
> 2. Give each thread its own connection, and don't interchange libpqxx
> objects between threads. This may scale better or worse than using a
> single thread, depending on the job.
>
> 3. Lock whenever you access any libpqxx object that may also be accessed
> by other threads. Think of each connection as a separate world, and all
> objects related to that connection are part of that world. Whenever
> multiple threads can step into the same world at the same time, acquire a
> lock that you associate with that world.
>
> The last option is the most flexible, but that also means it's dangerous.
> For example, you must make sure that you don't try to open a transaction
> on a connection while another thread still has a transaction open on the
> same connection. I would use option 3 only for connection pooling.
>
>
> Jeroen
>
>
>
Thanks Jeroen, I am trying to get around with a connection_pool model. I
am getting this error:
what(): FATAL: sorry, too many clients already
What's the upper limit of concurrent connection pqxx supports? what
freedom do I have to adjust it?
Fei
P.S. My resource_pool implementation, might be useful for libpqxx to
implement a concurrent model:
#ifndef UTILS_resource_POOL
#define UTILS_resource_POOL
#include <list>
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
namespace utils{
template <typename C, typename init_type = std::string>
struct resource{
C c;
bool used;
unsigned int id;
static unsigned int sid;
resource(const init_type & init): c(init), used(false) { id =
sid++;}
bool operator < (const resource<C, init_type> & cc) const {
return id < cc.id;
}
bool operator == (const resource<C, init_type> & cc) const {
return id == cc.id;
}
};
template <typename C, typename init_type> unsigned int resource<C,
init_type>::sid = 0;
template <typename C, typename init_type = std::string>
class resource_pool{
typedef typename boost::shared_ptr<resource<C, init_type> >
ele_type;
typedef typename std::list<ele_type> pool_type;
pool_type free_pool;
pool_type used_pool;
init_type init;
boost::mutex mutex;
typedef typename pool_type::const_iterator c_it_type;
typedef typename pool_type::iterator it_type;
public:
resource_pool(const init_type & init) : init(init){ }
C & alloc(unsigned int & id){
boost::mutex::scoped_lock lock(mutex);
if(free_pool.empty()){
ele_type conn = ele_type(new resource<C, init_type>(init));
conn->used = true;
used_pool.push_front(conn);
id = conn->id;
return conn->c;
}else{
it_type it = free_pool.begin();
ele_type conn = *it;
conn->used = true;
free_pool.erase(it);
used_pool.push_front(conn);
id = conn->id;
return conn->c;
}
assert(0);
}
void release(unsigned int id){
boost::mutex::scoped_lock lock(mutex);
it_type it = used_pool.begin();
while((*it)->id != id && it != used_pool.end()){
//std::cerr << (*it)->id << std::endl;
++it;
}
assert(it != used_pool.end());
ele_type conn = *it;
conn->used = false;
used_pool.erase(it);
free_pool.push_front(conn);
}
void dump(){
boost::mutex::scoped_lock lock(mutex);
std::cerr << "free_pool: " << std::endl;
c_it_type it = free_pool.begin();
while(it != free_pool.end()) {
std::cerr << (*it)->id << ": " << (*it)->used << std::endl;
++it;
}
std::cerr << "used_pool: " << std::endl;
it = used_pool.begin();
while(it != used_pool.end()) {
std::cerr << (*it)->id << ": " << (*it)->used << std::endl;
++it;
}
}
};
}
#endif
_______________________________________________
Libpqxx-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/libpqxx-general