List:MySQL++« Previous MessageNext Message »
From:Damien Kick Date:July 11 2014 7:44pm
Subject:Re: Problem with attempt to share a Connection between threads
View as plain text  
On Jul 11, 2014, at 1:33 PM, Warren Young
<mysqlpp@stripped<mailto:mysqlpp@stripped>>
 wrote:

On Jul 11, 2014, at 10:54 AM, Damien Kick
<dkick@stripped<mailto:dkick@stripped>> wrote:

But I was under the impression that sharing a Connection object between threads should be
okay.

Only in strictly limited ways.

The underlying MySQL C API library will not allow two simultaneous queries on a single
connection — lowercase “C”.  Thus, if you have no way to mediate access
to the Connection object — such as a ConnectionPool — you’re likely to
run into trouble.

Ah, I see.  I have obviously made a few mistakes in my understanding of the tutorial but
thanks for being patient and not assuming that I am just hacking blindly away and
expecting thread safety for free.  Now I know that I misunderstood this statement in the
user manual: "If your program’s connection-management strategy allows a thread to
use a Connection object that another thread created, you need to know
aboutConnection::thread_start(). This function sets up per-thread resources needed to
make MySQL server calls."  I had mistakenly thought this meant that thread_start
initialized per thread storage, e.g. pthread_key_create, to allow for exactly that, i.e.
two simultaneous queries.  My bad.

But my first attempt at a small exercise in using a Connection had started with the simple
thing first; i.e., "… just create a separarate Connection object for each thread
that needs to make database queries."  My previous version of zeros with a Connection per
thread, was finding an error, too, though.  I had been assuming that in this case
(Connection per thread) there was/is no need for mysqlpp::Connection::thread_start();
i.e., the manual states that "you don’t need to call it when you use the
simpleConnection-per-thread strategy, because this function is implicitly called the
first time you create a Connection in a thread." However, I had found
<http://lists.mysql.com/bugs/15740> which mentioned "My apologies, I haven't tested
yet, but I am pretty sure it is because I forgot to use
mysql_thread_init()/mysql_thread_end()," so I was not sure if I was understanding
correctly.  Now I know that the attempt to share a Connection between threads will not
work, I'm still perhaps confused about the Connection per thread example.

$ cat ~/tmp/dbench/src/zeros.og.cc
#include "zeros.hh"
#include <mysql++/mysql++.h>
#include <boost/thread.hpp>
#include <string>

int main()
{
    boost::thread_group threads;
    auto lambda = [] () {
        my::work("…", "…", "…", "…");
    };

    const auto start_time = boost::chrono::steady_clock::now();

    for (auto n = 0; n < 8; ++n) {
        threads.create_thread(lambda);
    }
    threads.join_all();

    const auto end_time = boost::chrono::steady_clock::now();
    const auto elapsed = end_time - start_time;
    typedef boost::chrono::duration<float> Seconds;
    const auto seconds = boost::chrono::duration_cast<Seconds>(elapsed);
    std::cout << "Exec time (in seconds): " << seconds.count() << '\n';
}

void my::work(
    const std::string& db_name,
    const std::string& server,
    const std::string& username,
    const std::string& password)
{
    assert(mysqlpp::Connection::thread_aware());
    mysqlpp::Connection cxn(
        db_name.c_str(), server.c_str(), username.c_str(),
        password.c_str());
    for (auto n = 0; n < 100; ++n) {
        auto query = cxn.query("SET @zero = 0");
        query.exec();
    }
}
$ ./zeros.og
Segmentation fault: 11 (core dumped)
$ ./zeros.og
Exec time (in seconds): 18.1346
$ ./zeros.og
Segmentation fault: 11 (core dumped)
$ ./zeros.og
Segmentation fault: 11 (core dumped)
$ ./zeros.og
Exec time (in seconds): 19.5771
$ gdb zeros.og
…
(gdb) run
Starting program: /Users/dkick/tmp/dbench/bld/debug/zeros
Reading symbols for shared libraries ++++++++.............................. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
[Switching to process 21686 thread 0x1503]
0x00000001000b88de in my_stat ()
(gdb) info threads
  10 "com.apple.libdispatch-manager" 0x00007fff92ddcd16 in kevent ()
  9                                 0x00007fff96a41f7e in spin_lock$VARIANT$mp ()
  8                                 0x00007fff96a41f79 in spin_lock$VARIANT$mp ()
  7                                 0x00007fff92ddc2aa in recvfrom ()
  6                                 0x00007fff92ddc2aa in recvfrom ()
* 5                                 0x00000001000b88de in my_stat ()
  4                                 0x00007fff92ddc2aa in recvfrom ()
  3                                 0x00007fff92ddc2aa in recvfrom ()
  2                                 0x00007fff92ddc2aa in recvfrom ()
  1 "com.apple.main-thread"         0x00007fff92ddc0fa in __psynch_cvwait ()
(gdb) bt
#0  0x00000001000b88de in my_stat ()
#1  0x0000000000000000 in ?? ()
(gdb)



________________________________

This e-mail and any attachments are confidential. If it is not intended for you, please
notify the sender, and please erase and ignore the contents.

Thread
Problem with attempt to share a Connection between threadsDamien Kick10 Jul 2014
  • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014
    • Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
      • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014
        • Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
          • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014
            • Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
              • Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
                • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014
              • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014
                • Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
                  • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014
                    • Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
                      • Re: Problem with attempt to share a Connection between threadsAdrian Cornish11 Jul 2014
  • Re: Problem with attempt to share a Connection between threadsChris Frey13 Jul 2014
Re: Problem with attempt to share a Connection between threadsDamien Kick11 Jul 2014
  • Re: Problem with attempt to share a Connection between threadsWarren Young11 Jul 2014