Results 1 to 5 of 5

Thread: Queuing QMetaObject::invokeMethod

  1. #1
    Join Date
    Dec 2007
    Location
    London
    Posts
    206
    Thanks
    40
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Queuing QMetaObject::invokeMethod

    Hello,

    I want to distribute requests from a system to a limited number of threads. I can run a request on the thread using signals/slots or QMetaObject::invokeMethod function. But I also want to buffer the incoming requests for running them later when a thread becomes available.

    For example I have a function call like:

    Qt Code:
    1. QMetaObject::invokeMethod(worker, "queryCustomCommand", Q_ARG( qint64 , trans ) ,Q_ARG( QString, sql ));
    To copy to clipboard, switch view to plain text mode 
    or :
    Qt Code:
    1. QMetaObject::invokeMethod(worker, "getTagLastChangeTime", Q_ARG( pQueryValueRequest_t ,req ) ,Q_ARG( qint64, trans ));
    To copy to clipboard, switch view to plain text mode 

    These should be buffered in an appropriate way.
    I tried to create a list of struct representing the method and arguments. But I couldnt find a way to represent the Q_ARG vars in the struct:

    Qt Code:
    1. struct StackItem{
    2. char* methodName;
    3. QList<QGenericArgument> argList;
    4. };
    To copy to clipboard, switch view to plain text mode 

    Here I couldnt form the "argList" element.(Compile errors, etc...)
    What is the right way of queuing these function calls?

    Thanks in advance,
    Yigit

  2. #2
    Join Date
    Dec 2007
    Location
    London
    Posts
    206
    Thanks
    40
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Queuing QMetaObject::invokeMethod

    I figured out that I can queue arguments in that form:

    Qt Code:
    1. StackItem stim;
    2. QGenericArgument gar1 = Q_ARG( qint64 ,trans );
    3. QGenericArgument gar2 = Q_ARG( QString, sql );
    4. stim.argList.append(gar1);
    5. stim.argList.append(gar2);
    6. stim.metname = "queryCustomCommand";
    To copy to clipboard, switch view to plain text mode 

    But when i call :

    Qt Code:
    1. QMetaObject::invokeMethod(worker, stim.metname.toLocal8Bit().data(), stim.argList.at(0) , stim.argList.at(1));
    To copy to clipboard, switch view to plain text mode 

    works correctly most of the time. But sometimes sends some wrong and unmeaningful parameters to thread. And sometimes crashes.

    Any idea?
    Thanks..

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Queuing QMetaObject::invokeMethod

    I am wondering if you would not be better of using a threadpool and delegating tasks to it.

    See QThreadPool.

    Cheers,
    _

  4. #4
    Join Date
    Dec 2007
    Location
    London
    Posts
    206
    Thanks
    40
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Queuing QMetaObject::invokeMethod

    Thanks Anda,

    The problem is that my classes are not inherited from QRunnable.
    I am just moving them into thread and adding to a watch list:

    Qt Code:
    1. ProjectDatabase *worker = prepareDbConnection();
    2. QThread* thread = new QThread;
    3. worker->moveToThread(thread);
    To copy to clipboard, switch view to plain text mode 

    I havent used QThreadPool before. I think my worker class should inherit from QRunnable. That may change lots of things in my code.

    I mainly have a constant number of database connection threads. I want to keep these connections active. And I am keeping track of which connections are available for new queries. When a query or a custom request arrives , I am directing the query to that connection.

    Is it possible to achieve this without changing too much things or I should port everything to Qthreadpool, Qrunnable domain?

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Queuing QMetaObject::invokeMethod

    Ah, I see, that isn't a very good fit for a QThreadPool and you are basically implementing your own similar mechanism.

    However, I am wondering if you could not do a similar task queue.

    Usually a thread pool worker runs like this

    1) start up and initialization: here yours would open the database connection
    2) wait on a task queue
    3) if a task is enqueued, dequeue it and process it
    4) repeat at 2

    The data entry structure in a custom task queue can be anything you want.

    Depending on whether the worker's run an explicit loop or an event loop the queue wait would either be e.g. a QWaitCondition wait or the event loop idling and waiting for a signal.

    Cheers,
    _

  6. The following user says thank you to anda_skoa for this useful post:

    yagabey (21st March 2017)

Similar Threads

  1. QHash as QMetaObject::invokeMethod argument
    By ^NyAw^ in forum Qt Programming
    Replies: 2
    Last Post: 1st October 2014, 19:04
  2. Problems with QMetaObject::invokeMethod
    By AlphaWolf in forum Qt Programming
    Replies: 3
    Last Post: 13th September 2012, 12:57
  3. Closing dialog by QMetaObject::invokeMethod - safe?
    By Blood9999 in forum Qt Programming
    Replies: 7
    Last Post: 16th August 2012, 13:48
  4. How to use QMetaObject::invokeMethod?
    By niko in forum Qt Programming
    Replies: 3
    Last Post: 26th January 2008, 17:02
  5. Using QMetaObject::invokeMethod() doesn't work
    By bruccutler in forum Qt Programming
    Replies: 2
    Last Post: 21st February 2007, 23:40

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.