为每个参数类型重新定义相同模式

时间:2014-11-18 19:06:38

标签: c++ multithreading qt

我不得不同步一个线程不安全的输出函数,这样当多个线程试图同时与标准输出交互时它不会崩溃。我做了一些C,但我对C ++编程很新。在C中通常没有那么多泛型函数,但在C ++中我可以看到一个方法或重载运算符,甚至有十个或更多版本具有不同的参数类型。

在我的程序中,我锁定了运算符<< QTextStream的另一个函数print()调用QTextStream :: operator<<。我想改变我的代码,每当我调用QTextStream :: operator<<时,它自动成为互斥锁定版本。怎么办呢?

另外,一个小小的问题是,当我将QMutex全局变量作为print()的局部变量放入时,为什么我的代码不起作用?

QTextStream qout(stdout);
QMutex mutex;

template<typename T>
void print(T t)
{
    QMutexLocker locker(&mutex);
    qout << t << flush;
}

class my_thread : public QThread
{
public:
    int n;

    my_thread()
    {
        n = 0;
    }

    void run()
    {
        while(n < 10)
        {
            print(n++);
            msleep(500);
        }
    }
};

int main()
{
    enum { N_THREADS = 10 };
    std::array<my_thread, N_THREADS> thread_array;
    for (auto& thread : thread_array)
    {
        thread.start();
    }
    for (auto& thread : thread_array)
    {
        thread.wait();
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

这个(未经测试)怎么样?

class LockedTextStream {
private:
  QMutex mutex;
  QTextStream textStream;

public:
  template <class... Args>
  LockedTextStream(Args&&... args) : textStream(std::forward<Args>(args)...) {}

  template <class T>
  LockedTextStream& operator<<(const T& t) {
    QMutexLocker locker(&mutex);
    textStream << t;
    return *this;
  }
};

LockedTextStream sharedStream(stdout);

...
    sharedStream << n++;
....

这个包装器应该接受任何构造函数参数并将它们转发到QTextStream,并且应该锁定对operator&lt;&lt;()的任何调用。

QMutex不能是函数内部的局部变量的原因是互斥量是在该函数的上下文中分配的。互斥体的重点在于您在每个线程中运行相同的互斥锁。