了解 qthread 子类的 run 方法和线程上下文

发布于 2024-10-21 01:38:01 字数 955 浏览 6 评论 0原文

我有一个带有很多方法的编码器类。这是 Qthread 的子类。我是多线程新手

试图理解这个类是怎样的 线程化其方法

...我理解线程化它必须位于 qthread 子类中的方法。并且它的运行实现了该类的线程代码。仅当调用此类对象的 start 方法时,线程才会启动。

问题:首先你推断出什么 从这次运行实现

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();
}

问题:线程上下文的含义是什么 与其方法有关。

问题:如果使用此方法会发生什么 类在该类之前被调用 线程已启动

i have an encoder 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长发绾君心 2024-10-28 01:38:01
  1. 您编写的类创建一个线程并初始化一个 QObject::timer。然后它继续调用用户定义的 init() 函数,然后调用 QThread::exec () 函数。

    1. 我的猜测是,您希望 exec() 是一个用户定义的函数,实际工作将在其中发生。请注意,QThread::exec() 处理线程的 Qt 事件队列。
    2. 此外,在某些平台上,您可能会收到“从线程创建计时器时出错”警告消息。我在 Windows 上遇到了这个错误,而代码在 Linux 上执行得很好
    3. 此外,请注意,如果您不调用 QThread::exec() 函数或 QApplication::processEvents() 来自您的线程。
  2. Qt 中的线程上下文与任何其他线程概念相同。也就是说,所有内存都在线程代码之间共享(此时在“run()”函数中输入)。以及调用您的对象的任何其他上下文。如果此对象可能在线程中执行并从线程外部访问,则您必须保护共享数据。

  3. 因为所有数据在线程上下文之间共享(它是共享内存多处理模型),所以在线程执行之前/之后/期间调用函数没有问题。鉴于:
    1. 在调用任何方法之前,对象已完全构造完毕。这对于线程来说并不特殊,除非该对象是在线程中创建的。
    2. 任何数据成员都受到互斥锁的保护(我在#2 中回避了这一点)。 QMutexLocker 是一种方便的基于堆栈的 RAII 方法,用于处理 Qt 中的互斥锁。< /里>

我相信我在这里完全回答了您的问题,所以我将继续链接到 RAII 和 < a href="http://blog.emptycrate.com/taxonomy/term/38" rel="nofollow">线程 我在另一个网站上写的文章,仅供进一步参考。

编辑:有关线程场景的特殊性:

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
}
  • 注意:调查 QFuture 是个好主意,它旨在处理这种异步任务,就像编码器一样,您正在查看 QFuture 将避免共享数据和死锁的一些潜在线程问题。
  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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文