开发者

understanding a qthread subclass's run method and thread context

i have an enco开发者_JS百科der class with lots of methods . this is a subclass of Qthread. i am new to multi-threading and

trying to understand how this class is threading its methods

... i understand to thread a method it has to be in a subclass of qthread. and the run of this implements the threaded code for this class. And the thread starts only when a call to start method on the object of this class is made.

Question : firstly what do you infer from the this run implementation

void Encoder::run(void)
{
    VERBOSE(VB_DEBUG, "Encoder::run");

    if (WILL_PRINT(VB_DEBUG))
        print_stats_timer_id = QObject::startTimer(kEncoderDebugInterval);
    health_check_timer_id = QObject::startTimer(kEncoderHealthCheckInterval);

    if (init())
        exec();
    else
        VERBOSE(VB_ERROR, "Encoder::run -- failed to initialize encoder");

    QObject::killTimer(health_check_timer_id);
    if (print_stats_timer_id)
        QObject::killTimer(print_stats_timer_id);

    cleanup();
}

Question: what does thread context mean in relation to its methods .

also

Question: what would happen If a method of this class is called before this class's thread has started


  1. The class you have written creates a thread and initializes a QObject::timer. It then goes on to call a user defined init() function then the QThread::exec() function.

    1. My guess is that you intended that exec() would be a user defined function where the actual work is to occur. Be aware that QThread::exec() processes the thread's Qt Event Queue.
    2. Also, on some platforms you may get an "Error creating timer from thread" warning message. I've encountered this error on Windows when the code executed fine on Linux
    3. Also, be aware that your timer will never occur if you do not call the QThread::exec() function or QApplication::processEvents() from within your thread.
  2. Thread context in Qt is the same as any other thread concept. That is, all memory is shared between the threaded code (entered at this point in your "run()" function). And any other context which calls into your object. If this object may ever be executing in a thread and accessed from outside of the thread you must protect the shared data.

  3. Because all data is shared between thread contexts (it's a shared memory multiprocessing model) there is no problem with calling functions before/after/during thread execution. Given that:
    1. The object is fully constructed before you call any method. This is not special to threads, necessarily, unless the object is created in a thread.
    2. Any data member is protected with a mutex lock (I eluded to this in #2). QMutexLocker is a handy stack based RAII way of dealing with mutex locks in Qt.

I believe I fully answered your question here, so I'll go ahead and link to RAII and threading articles I have written on another site, just for further reference.

Edit: specificity about threading scenarios:

class MyThreadedClass : public QThread
{
  MyThreadClass(const boost::shared_ptr<SomeOtherClass> &t_object)
    : m_object(t_object) {}

  void doSomething()
  {
    // Depending on how this method was called (from main, from internal thread)
    // will determine which thread this runs on, potentially complicating thread
    // safety issues.
    m_object->someThing(); 
  }

  void run()
  {
    // I'm now in a thread!
    m_object->someFunction(); // oops! The call to someFunction is occurring from 
                              // a thread, this means that SomeOtherClass must be 
                              // threadsafe with mutex guards around shared 
                              // (object level) data.
    // do some other stuff
  }
};

int main()
{
  MyThreadClass thread(someobjectfromsomewhere);
  thread.start(); // MyThreadClass is now running
  thread.doSomething(); // The call to doSomething occurs from main's thread.
                        // This means 2 threads are using "thread", main 
                        // and "thread"'s thread. 
  // The call to thread.doSomething hits Thread.m_object, which means that 
  // now multiple threads are also accessing m_object ("thread" and "main").
  // This can all get very messy very quickly. It's best to tightly control 
  // how many threads are hitting an object, and how
}
  • NOTE: It would be a good idea to investigate QFuture, which is designed to handle this kind of asynchronous task, like an encoder, that you are looking at QFuture will avoid some of the potential threading issues of shared data and deadlocks.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜