Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Linux threading seems to be broken with Qt 4.8.0
Forum Updated to NodeBB v4.3 + New Features

Linux threading seems to be broken with Qt 4.8.0

Scheduled Pinned Locked Moved General and Desktop
5 Posts 5 Posters 2.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    redusek
    wrote on last edited by
    #1

    I've got a simple database application.

    It launches two threads. Each thread attempts to update the same record in a Postgres database using a transaction.

    The transaction logic is this:

    Start the transaction
    Update the record
    Sleep for a few seconds
    Commit the transaction

    (See code down down at the bottom of the post)

    The problem I'm having is that when I launch two threads to do this, my application hangs.

    What happens is this:

    Thread one Starts the transaction
    Thread one updates the record
    Thread one sleeps
    Thread two starts the transaction
    Thread two attempts to update the record

    Then, nothing else. The whole program locks. I have determined that Thread two cannot update the db record because the record is locked by the transaction from Thread one. However, for a threaded application, Thread one should be able to complete its work and then after it commits Thread two can carry on.

    I've tested it on Windows and, indeed, it works like such on Windows...

    Thread one Starts the transaction
    Thread one updates the record
    Thread one sleeps
    Thread two starts the transaction
    Thread two attempts to update the record (and blocks)
    Thread one wakes up from sleeping
    Thread one commits the transaction
    Thread two successfully updates the database record.
    Thread two commits the transaction.
    Program exits normally.

    And, when I run two separate instances of the program (ie. separate processes) on Linux, each process only executing a single thread, they work in lock-step just as the threads worked on Windows.

    So, separate processes behave correctly on Linux, but the threads aren't working as I'd expect.

    Can someone straighten me out on Linux threading? Is my application somehow being compiled without threading? I can see in the make output that it's using -lpthread...

    Make output
    @
    make debug
    make -f Makefile.Debug
    make[1]: Entering directory /media/TMP/TestODBC' g++ -c -pipe -g -O0 -Wall -W -D_REENTRANT -DQT_SQL_LIB -DQT_CORE_LIB -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/mkspecs/default -I. -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtCore -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtSql -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include -Idebug -o debug/ODBCExample.o ODBCExample.cpp g++ -c -pipe -g -O0 -Wall -W -D_REENTRANT -DQT_SQL_LIB -DQT_CORE_LIB -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/mkspecs/default -I. -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtCore -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtSql -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include -Idebug -o debug/main.o main.cpp main.cpp:7: warning: unused parameter ‘argc’ /opt/QtSDK/Desktop/Qt/4.8.0/gcc/bin/moc -DQT_SQL_LIB -DQT_CORE_LIB -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/mkspecs/default -I. -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtCore -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtSql -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include -Idebug ODBCExample.h -o debug/moc_ODBCExample.cpp g++ -c -pipe -g -O0 -Wall -W -D_REENTRANT -DQT_SQL_LIB -DQT_CORE_LIB -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/mkspecs/default -I. -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtCore -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include/QtSql -I/opt/QtSDK/Desktop/Qt/4.8.0/gcc/include -Idebug -o debug/moc_ODBCExample.o debug/moc_ODBCExample.cpp g++ -Wl,-rpath,/opt/QtSDK/Desktop/Qt/4.8.0/gcc/lib -o ODBCExampleD debug/ODBCExample.o debug/main.o debug/moc_ODBCExample.o -L/opt/QtSDK/Desktop/Qt/4.8.0/gcc/lib -lQtSql -lQtCore -lpthread { test -n "" && DESTDIR="" || DESTDIR=.; } && test $(gdb --version | sed -e 's,[^0-9]\+\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index $DESTDIR" -ex quit 'ODBCExampleD' && test -f ODBCExampleD.gdb-index && objcopy --add-section '.gdb_index=ODBCExampleD.gdb-index' --set-section-flags '.gdb_index=readonly' 'ODBCExampleD' 'ODBCExampleD' && rm -f ODBCExampleD.gdb-index || true make[1]: Leaving directory /media/TMP/TestODBC'
    @

    Transaction logic
    @
    bool ODBCExample::RunThreadedTransaction(QString connectionName,
    int sleepSeconds)
    {
    QSqlDatabase::addDatabase("QODBC3", connectionName);

    qDebug() << QSqlDatabase::connectionNames().join("|");

    QSqlDatabase db = QSqlDatabase::database(connectionName, false);

    qDebug() << "[" << connectionName << "] db address: " << &db;
    qDebug() << "[" << connectionName << "] db.isValid: " << db.isValid();
    qDebug() << "[" << connectionName << "] connect options: "
    << db.connectOptions();
    qDebug() << "[" << connectionName << "] connection name: "
    << db.connectionName();
    qDebug() << "[" << connectionName << "] driver name: " << db.driverName();
    QSqlDriver *dbd = db.driver();
    qDebug() << "[" << connectionName << "] db.driver: " << dbd;

    db.setDatabaseName("PostgresDSN;BoolsAsChar=0");
    db.setUserName("myuser");
    db.setPassword("mypassword");

    if (!db.open())
    {
    qDebug() << "[" << connectionName << "] database wasn't opened";
    qDebug() << "[" << connectionName << "] " << db.lastError();
    return false;
    }

    qDebug() << "[" << connectionName
    << "] database successfully opened for connection 1";

    // bool trans = dbd->beginTransaction();
    bool trans = db.transaction();
    qDebug() << "[" << connectionName << "] trans: " << ((trans) ? "true"
    : "false");

    if (trans)
    {
    QSqlQuery query(db);
    QString strUpdateUsers =
    "UPDATE mytable SET mynumber = mynumber + 1 WHERE myid = 102";
    query.exec(strUpdateUsers);
    qDebug() << "[" << connectionName << "] update finished";
    sleep(sleepSeconds);
    db.commit();
    qDebug() << "[" << connectionName << "] trans commited";
    }
    else
    {
    qDebug() << "[" << connectionName << "] trans could not be started";
    }

    return true;
    }
    @

    1 Reply Last reply
    0
    • T Offline
      T Offline
      tucnak
      wrote on last edited by
      #2

      Qt is well-tested, so, in my opinion something wrong in your code instead of Qt code

      1 Reply Last reply
      0
      • M Offline
        M Offline
        morinehtar0
        wrote on last edited by
        #3

        You may need to add thread support in your .pro file;

        CONFIG += thread

        Documentation:
        http://qt-project.org/doc/qt-4.8/qmake-project-files.html

        1 Reply Last reply
        0
        • V Offline
          V Offline
          vezprog
          wrote on last edited by
          #4

          Make sure your using QMutex's since your using multiple threads. I have used multiple threads on Linux for Qt on 4.8.0 and have had no problems...

          1 Reply Last reply
          0
          • G Offline
            G Offline
            goetz
            wrote on last edited by
            #5

            If you use the very same database connection on two different threads, you might run into problems. The database classes are not thread safe! You will need distinct connections for each thread.

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved