English 中文(简体)
• 知道何时从另一个透镜开始“三面”活动
原标题:Knowing when a QThread s event loop has started from another thread

在我的节目中,我分门别类。

void ManagerThread::run() {

    // do a bunch of stuff,
    // create some objects that should be handled by this thread
    // connect a few signals/slots on the objects using QueuedConnection

    this->exec(); // start event loop
}

现在,在另一个版面(即:MainThread)中,我开始使用<代码>ManagerThread/code>和wait for its started(<>/code> sign,此后,我着手使用应由ManagerThread处理的信号和位置。 然而,started(> sign is fundamental emmitted right before run(),因此,根据阅读时间安排,我从MainThread中失去一些信号,因为活动周期尚未开始!

(EDIT:发现,问题不是,而是信号没有及时连接,原因相同)

我可在打电话exec()之前发出信号,但这也引起麻烦。

是否有任何确切/简单的方法知道事件的发生已经开始?

感谢!

<>strong>EDIT2: (SOLUTION)

坦率地说,这个问题恰恰是我所说的。 活动 lo头开始就是一个问题,因为信号should在开始之前就已经停止。 问题在于,一些信号不会及时连接起来,因为<条码>启动(<>>>>/代码>信号在<条码>run(<>>>>之前发出。

解决办法is,在外围所有联系和权利之后发出另一条习俗信号。 这样,所有信号/位置都得到保证。

这是my问题的解决办法,但不是真实的答案。 我接受了does回答标题的答复。

我把我的所有法典留给了这些好奇的人,解决办法是等待<编码>instance()方法中的另一个信号。


<<>CODE>:

Many of you are saying that I cannot lose signals, so here is my whole class implementation. I will simplify it to just the bare necessities.

此处为<代码>的接口。 ManagerThread:

// singleton class
class ManagerThread: public QThread {

    Q_OBJECT

    // trivial private constructor/destructor

    public:
    static ManagerThread* instance();

    // called from another thread
    public:
    void doSomething(QString const& text);

    // emitted by doSomething,
    // connected to JobHandler whose affinity is this thread.
    signals:
    void requestSomething(QString const& text);

    // reimplemented virtual functions of QThread
    public:
    void run();

    private:
    static QMutex s_creationMutex;
    static ManagerThread* s_instance;
    JobHandler* m_handler; // actually handles the requests
};

一些相关的执行。 2. 创建直线区:

ManagerThread* ManagerThread::instance() {
    QMutexLocker locker(&s_creationMutex);
    if (!s_instance) {
        // start socket manager thread, and wait for it to finish starting
        s_instance = new ManagerThread();

        // SignalWaiter essentially does what is outlined here:
        // http://stackoverflow.com/questions/3052192/waiting-for-a-signal
        SignalWaiter waiter(s_instance, SIGNAL(started()));
        s_instance->start(QThread::LowPriority);
        qDebug() << "Waiting for ManagerThread to start";
        waiter.wait();
        qDebug() << "Finished waiting for ManagerThread thread to start.";
    }

    return s_instance;
}

• 重新实施设置信号/位置和启动活动周期的运行:

void ManagerThread::run() {
   // we are now in the ManagerThread thread, so create the handler
   m_handler = new JobHandler();

   // connect signals/slots
   QObject::connect(this,
                    SIGNAL(requestSomething(QString const&)),
                    m_handler,
                    SLOT(handleSomething(QString const&)),
                    Qt::QueuedConnection);

   qDebug() << "Starting Event Loop in ManagerThread";

   // SOLUTION: Emit signal here and wait for this one instead of started()

   this->exec(); // start event loop
}

Function that delegates the handling to the correct thread. This is where I emit the signal that is lost:

void ManagerThread::doSomething(QString const& text) {

    qDebug() << "ManagerThread attempting to do something";

    // if calling from another thread, have to emit signal
    if (QThread::currentThread() != this) {
        // I put this sleep here to demonstrate the problem
        // If it is removed there is a large chance the event loop
        // will not start up in time to handle the subsequent signal
        QThread::msleep(2000);  
        emit(requestSomething(text));
    } else {
       // just call directly if we are already in the correct thread
       m_handler->handleSomething(text);
    }
}

Finally, here is the code from MainThread that will fail if the event loop doesn t start in time:

ManagerThread::instance()->doSomething("BLAM!");

假设手稿只是打印出其文本,那是成功版本的:

Waiting for ManagerThread to start
Finished waiting for ManagerThread thread to start.
Starting Event Loop in ManagerThread
ManagerThread attempting to do something
BLAM!

这里是一场失败:

Waiting for ManagerThread to start
Finished waiting for ManagerThread thread to start.
ManagerThread attempting to do something
Starting Event Loop in ManagerThread

Clearly the event loop started after the signal was emitted, and BLAM never prints. There is a race condition here, that requires the knowledge of when the event loop starts, in order to fix it.

也许我没有东西,问题有些不同。

Thanks so much if you actually read all that! Phew!

最佳回答

如果你确定这些联系是正确的,那么你就不应失去信号。 但是,如果你真的想在read光活动周期开始时收到通知,那么你可以在打电话<条码>之前,尝试<条码>:singleShot(>。 活动开始时,只交付一次。

问题回答

参看rel=“nofollow”QSemaphore,在深层之间发出信号。 时间档和信号对于同一线上的事件和呼吁来说更好。

Edit: Alternately you could combine QMutex with QWaitCondition if a semaphore is not applicable. More example code to see how you are using the ManagerThread in conjunction with the MainThread would be helpful.

这是非问题。 校对之间的信号被问到(更具体地说,你需要将其放在<条码>连接()中,因为校对之间的直接联系是安全的。

你们可以在经理人大楼里建立信号/位置联系。 这样,他们就连起来,甚至连(......)被叫来。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签