• 2424阅读
  • 11回复

[讨论]QT多线程互斥变量是否有支持自旋锁的功能? [复制链接]

上一主题 下一主题
离线wwwfffhhh
 

只看楼主 倒序阅读 楼主  发表于: 2021-05-07
qt的QMutex变量没有看到设置自旋锁的函数,也就是类似window系统的 InitializeCriticalSectionAndSpinCount(...)的设置自旋锁的参数,不知道QT是否有类似这种互斥量?
离线wwwfffhhh

只看该作者 1楼 发表于: 2021-05-07
程序需要在Linux系统下运行,并且我现在QT编写的程序需要多线程高性能处理,所以需要设置这个参数,不知道有什么方法解决?
在线snow_man_0

只看该作者 2楼 发表于: 2021-05-07
回 wwwfffhhh 的帖子
wwwfffhhh:程序需要在Linux系统下运行,并且我现在QT编写的程序需要多线程高性能处理,所以需要设置这个参数,不知道有什么方法解决? (2021-05-07 22:48) 

Qt多线程计算和OPENMP的性能差不多的
离线wwwfffhhh

只看该作者 3楼 发表于: 2021-05-08
你的意思是QMutext内部已经设置了自旋锁吗?否则CPU总是需要线程核心态和用户态切换的,所以就比较慢?
离线deepgui

只看该作者 4楼 发表于: 2021-05-08
你觉得不够可以使用C++里的mutex
离线realfan

只看该作者 5楼 发表于: 2021-05-10
自旋锁,可以用C++自己写一个,网上也很多。

#include <atomic>
class SpinLock {
  public:
    SpinLock() : _flag(false) {}
    void lock() {
        bool expect = false;
        while (!_flag.compare_exchange_weak(expect, true)) {
            expect = false;
        }
    }

    void unlock() {
        _flag.store(false);
    }

  private:
    std::atomic<bool> _flag;
};

离线wwwfffhhh

只看该作者 6楼 发表于: 2021-05-12
回 realfan 的帖子
realfan:自旋锁,可以用C++自己写一个,网上也很多。
#include <atomic>
class SpinLock {
  public:
....... (2021-05-10 17:15) 

虽然上方的程序线程会等待释放“锁”,但它是死循环等待,如果其它线程可能会花一段时间才会释放”锁“,那么这个CPU利用率就非常高,程序性能反而可能变得很差。


我希望的是线程只会等待少量时间(即可以设置自旋循环等待一定的次数),如果超过这个次数就线程休眠了
2条评分好评度+1贡献值+1
deepgui 好评度 +1 - 2021-05-16
deepgui 贡献值 +1 - 2021-05-16
离线realfan

只看该作者 7楼 发表于: 2021-05-12
回 wwwfffhhh 的帖子
wwwfffhhh:虽然上方的程序线程会等待释放“锁”,但它是死循环等待,如果其它线程可能会花一段时间才会释放”锁“,那么这个CPU利用率就非常高,程序性能反而可能变得很差。
我希望的是线程只会等待少量时间(即可以设置自旋循环等待一定的次数),如果超过这个次数就线程休眠了 (2021-05-12 08:51) 

自旋锁应用场景,就是在等待时间很短的情形。否则就用普通锁。可以考虑用混合锁,先自旋一定时间,未取得,再进入互斥休眠。
离线wwwfffhhh

只看该作者 8楼 发表于: 2021-05-13
回 realfan 的帖子
realfan:自旋锁应用场景,就是在等待时间很短的情形。否则就用普通锁。可以考虑用混合锁,先自旋一定时间,未取得,再进入互斥休眠。 (2021-05-12 10:05) 

你说得很对,但我现在就是没有找到“再进入互斥休眠”的代码程序
离线realfan

只看该作者 9楼 发表于: 2021-05-14
回 wwwfffhhh 的帖子
wwwfffhhh:你说得很对,但我现在就是没有找到“再进入互斥休眠”的代码程序 (2021-05-13 20:40) 

我见过有用std::mutex 先try_lock一定次数,或一定时间的,如果仍然未成功,再调用lock

但这种方式,效率如何,还是需要验证
离线deepgui

只看该作者 10楼 发表于: 2021-05-16
如果程序用线程有互锁问题,是程序设计问题。很多是逻辑问题,最好是从逻辑上去解决。
离线wwwfffhhh

只看该作者 11楼 发表于: 2021-08-14
基本自己解决了这个自旋锁的问题,就是自己定义一个类,封装了了原来的QRecursiveMutex。
参考代码如下:

    class QRecursiveMutexWithSpin
    {
    public:
        explicit QRecursiveMutexWithSpin(quint32 SpinCount_i)
            :SpinCount(SpinCount_i)
        {
        }

        inline void lock()
        {
            for(quint32 i = 0; i < SpinCount; i++)
            {
                if(InnerRecursiveMutext.tryLock())
                    return;
            }

            InnerRecursiveMutext.lock();
        }

        inline void unlock()
        {
            InnerRecursiveMutext.unlock();
        }

    private:
        QRecursiveMutex InnerRecursiveMutext;
        quint32 SpinCount = 0;//自旋次数
    };

快速回复
限100 字节
 
上一个 下一个