互斥锁锁定后如何处理主线程中的信号?

时间:2019-04-05 06:31:35

标签: c++ multithreading qt c++11 mutex

我正在编写一个多线程Qt应用程序,但是由于与OpenGL相关的调用,部分代码必须始终在主线程中执行。

模拟问题的粗糙代码将是:

QMutex mutex;

void openGLCalls()
{
}
void foo1()
{
    mutex.lock();
    openGLCalls();
    mutex.unlock();

}

class CBHandler : public QObject
{

public:
    CBHandler(QObject *parent = NULL)
    {
        connect(this, SIGNAL(requestCallbackExec()), SLOT(runCallback()),    Qt::BlockingQueuedConnection);

    }

    static CBHandler *Instance();

    public slots:

    void runCallback  ()
    {
        //in the main thread as object lies there
        openGLCalls();
    }

signals:
    void requestCallbackExec ();

};

class Thread1
{
    void run()
    {
        while(1)
        {
            mutex.lock();
            CBHandler::Instance()->emit requestCallbackExec();
            mutex.unlock();
        }
    }
};

void main()
{

    Thread1 thread;
    CBHandler cbhandler;
    thread.start();
    while(1)
    {
        if(/*some key pressed*/)
        {
            foo1();
        }
    }
}

以上代码确保“ openGLCalls()”始终在主线程中执行。 但是问题是,如果互斥锁被Thread1锁定,并且主线程尝试调用foo1,那么当试图锁定互斥锁时,主线程会进入休眠状态。 而且由于主线程处于休眠状态,因此线程1锁定的互斥锁永远不会因未请求“ requestCallbackExec”信号而被解锁。

1 个答案:

答案 0 :(得分:0)

您应该在sudo apt install flex-old等待时让事件循环旋转。似乎没有办法做到这一点。这样您就可以忙着等待:

Queue

您可以在public static void DoSomething(int x) { Console.WriteLine("Starting " + x); Thread.Sleep((x%10) * 1000); } public static void Main(string[] args) { Queue<int> myList = new Queue<int>(); for (int i = 0; i < 100; i++) myList.Enqueue(i); // This would be random if we'd use a List //Parallel.ForEach(myList, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, x => DoSomething(x)); // This will get the right order. But 2 can still be faster than 1 if 2's thread is quicker. But generally you got your order. Parallel.For( 0, // We count from 0 myList.Count, // to max entries.. new ParallelOptions() { MaxDegreeOfParallelism = 4 }, // don't forget this one ;) (x) => { lock (myList) { int y = myList.Dequeue(); Console.WriteLine(y); DoSomething(y); } }); } 调用中添加超时以不使CPU过热,但这会花费一些延迟。