这是使用Qt 4进行C ++ GUI编程的一个例子
我有一个线程类:
class Thread : public QThread {
Q_OBJECT
public:
Thread();
void setMessage(const QString &message);
void stop();
protected:
void run();
private:
QString messageStr;
volatile bool stopped;
}
这是该课程的相关实施:
Thread::Thread() {
stopped = false;
}
void Thread::run() {
while (!stopped)
std::cerr << qPrintable(messageStr);
stopped = false;
std::cerr << std::endl;
}
void Thread::stop() {
stopped = true;
}
此类用于ThreadDialog类,它基本上有两个私有字段Thread threadA
和Thread threadB
。 setMessage
函数分别为它们调用,messageStr
设置为&#34; A&#34;和&#34; B&#34;。内部声明了两个按钮,其中点击信号连接两个插槽功能,启动或停止这两个线程,如下所示:
void ThreadDialog::startOrStopThreadA() {
if (threadA.isRunning()) {
threadA.stop();
threadAButton->setText(tr("Start A"));
} else {
threadA.start();
threadAButton->setText(tr("Stop A"));
}
}
threadB的功能是相同的。问题在于,直接引用本书:&#34;已停止的变量被声明为volatile,因为它是从不同的线程访问的,我们希望确保每次需要时都会重新读取它。如果省略volatile关键字,编译器可能会优化对变量的访问,可能导致错误的结果。&#34;
我无法理解为什么这两个线程会访问同一个字段。 Aren他们是不同的实例,所以他们有自己的字段stopped
?此外,如果共享stopped
字段,为什么还没有共享messageStr
字段?
答案 0 :(得分:0)
这是多线程中常见的混淆。您将线程对象class Thread : public QThread
与执行线程(即执行指令)混淆。
ThreadDialog::startOrStopThreadA
Thread::run()
,由threadA.start()
启动。这两个主题都可以访问messageStr
和stopped
答案 1 :(得分:0)
我无法理解为什么这两个线程会访问同一个字段。他们不是不同的例子 所以他们有自己的领域停止?此外,如果共享停止字段,为什么不是messageStr 领域也分享了吗?
这不是他们所说的。无论是否涉及线程,该字段都不在不同实例之间共享。但是,可以从不同的线程访问实例,在这方面,字段可能在不同的线程之间“共享”。
他们正在谈论其他线程希望调用threadA.stop()
如果您有此代码:
Thread threadA;
threadA.start();
...
threadA.stop();
涉及2个主题:
threadA
调用threadA.start()
醇>
现在volatile bool stopped
由run()
函数中的线程2访问,并且在调用threadA.stop()
时从线程1访问它。
答案 2 :(得分:0)
两个实例threadA
和threadB
不共享stopped
。如果是同一个类,它们是不同的实例。
关于本声明:
已停止的变量被声明为volatile,因为它是从中访问的 不同的线程,我们希望确保它每次都是新鲜的 时间需要。
这意味着从两个不同的运行线程访问stopped
变量。这里两个线程是主应用程序线程和run()
函数中的线程。从两个不同的线程访问同一个变量是不安全的。