3.多线程系列文章 之 线程的同步[1/2]

目录

2.1 简介

2.2 Qmutex 应用

2.3 QWaitCondition 应用

 

接下来继续说线程同步的问题,当n个线程在一起运行时,为了控制其先后运行顺序,或者 对共享数据的访问 ,这就需要用到线程的功能,这仅是我能想到的两个情形.

 

QT 提供 QMutex, QReadWriteLock, QSemaphore  QWaitCondition  用以提供线程同步.这里就选用QMutex,QWaitCondition 结合一个 “下载工具” 例子  分别讲解说明,其他的以后需用到再说. 如果一篇文章全部讲完,实在够呛,能力有限

 

 

2.1 Qmutex 应用

     首先我们将使用 QMutex来实现 下载工具 中的 “下载/暂停/停止”三种下载状态切换,以下简称为状态切换。

       简单说一下Qmutex,该类是用来同步线程最基础的类。一般通过调用lock /unlock方法.使Qmutex就是像检测一个标志一样,如果不是true就继续等待,只不过这个等待的过程不会占用cpu时间片。这和循环检测每个标志位有明显的不同。

    使用QMutext需要注意的两点是:

    1.在同一线程中,Qmutex 不能重复lock或unlock,换句话说就是lock/unlock 只能成对出现。幸好的是如果你不小心这么做的时候,debug时有所提示.

     2.线程lock后,只能在同一个线程中进行unlock,例如,A线程lock后,如果企图在B线程直接unlock 来释放,这将会引发错误。

 

上回讲到线程的控制提到sleep是无法休眠到一半然后唤醒的. 使用Qmutex  可以改变 sleep完全没有回应的局面。在这里我们需要用一个变量做开关,使用Qmutex  做同步访问以达到一种唤醒的效果,也就是我们要做的状态切换了,只不过说法不同。

 

想象一下该下载工具,为了ui的响应,一般运行时有两个线程.一个是main线程用于gui,另一个是worker线程,用于下载数据,用户随时决定要进行状态切换.

 

下面是关键的代码部分

 

#include <QThread>
#include <QMutex>



class CThread : public QThread
{

public:
    CThread();
    ~CThread();
public:
    enum E_downloadState{DS_INIT,DS_START, DS_PAUSE, DS_STOP};
    void startDownload();
    void pauseDownload();
    void stopDownload();
    E_downloadState  downState() const;

protect:
    void run();

private:
    QMutex mDownloadMutex;
    E_downloadState  mState; //用于mutex的变量

    void setDownloadMutex(bool lock);
    void setDownState( E_downloadState state);

};

 

画个示意图

 

开始下载:

 clip_image002

 

 

暂停下载

clip_image004

 

中止下载

 clip_image006

 

 

 

 

 

在这里为了看清整个控制过程,我用qDebug()模拟出下载工具的状态切换

image

posted @ 2010-09-30 16:55  网络小虫  阅读(709)  评论(0编辑  收藏  举报