一个线程池的例子(二)

       Qt提供了QThread用于创建线程,在实际的使用过程中,我们需要派生一个QThread的子类,实现其中的run虚函数, 用的时候创建该类的实例,调用它的start方法。下面是一个使用QThread实现了一个简单的线程池。

def.h

#ifndef DEF_H
#define DEF_H

#include <QVector>
#include <math.h>
#include <QWaitCondition>
#include <QMutex>
#include <QDebug>

struct Task
{
    long m_StartValue;
    long m_EndValue;
    long m_MinResultValue;
    long m_MaxResultValue;
    __int64 m_SumResultValue;

    Task()
    {
        m_StartValue = 0;
        m_EndValue = 0;
        m_MinResultValue = 0;
        m_MaxResultValue = 0;
        m_SumResultValue = 0;
    }

    Task &operator=(const Task &T)
    {
        if (this != &T)
        {
            m_StartValue = T.m_StartValue;
            m_EndValue = T.m_EndValue;
            m_MinResultValue = T.m_MinResultValue;
            m_MaxResultValue = T.m_MaxResultValue;
            m_SumResultValue = T.m_SumResultValue;
        }

        return *this;
    }
};

static bool IsPrime(unsigned long n)
{
    if (n == 2)
    {
        return true;
    }

    if (n % 2 == 0 || n < 2)
    {
        return false;
    }

    long tmp = (int)sqrt((double)n);
    for (long i = 3; i <= tmp; i += 2)
    {
        if (n % i == 0)
        {
            return false;
        }
    }

    return true;
}

static void CalCulatePrime(Task &T)
{
    long PrimesCount = 0;

    for (long i = T.m_StartValue; i < T.m_EndValue; i++)
    {
        if (IsPrime(i))
        {
            PrimesCount++;

            if (PrimesCount == 1)
            {
                T.m_MinResultValue = i;
            }

            T.m_SumResultValue = T.m_SumResultValue + (__int64)i;
        }
    }

    PrimesCount = 0;
    for (long i = T.m_EndValue - 1; i >= T.m_StartValue; i--)
    {
        if (IsPrime(i))
        {
            PrimesCount++;

            if (PrimesCount == 1)
            {
                T.m_MaxResultValue = i;
                break;
            }
        }
    }

}

extern QVector<Task> g_TaskList;
extern QWaitCondition g_TaskStart;
extern QWaitCondition g_TaskFinished;
extern QMutex       g_TaskMutex;
extern int          g_TaskCount;

#endif

WorkThread.h

#ifndef WORKER_THREAD_H
#define WORKER_THREAD_H

#include "def.h"

#include <QThread>
#include <QObject>

class WorkerThread : public QThread
{
    Q_OBJECT

public:
    WorkerThread(QObject *parent = 0);
    virtual ~WorkerThread(void);

protected:
    void run();

};

#endif

WorkThread.cpp

#include "WorkerThread.h"

WorkerThread::WorkerThread(QObject *parent)
    : QThread(parent)
{
}


WorkerThread::~WorkerThread(void)
{
    wait();
}

void WorkerThread::run()
{
    g_TaskMutex.lock();
    while(g_TaskList.size() <= 0)
    {
        g_TaskStart.wait(&g_TaskMutex);
    }
    g_TaskMutex.unlock();

    while(1)
    {
        if (g_TaskList.size() == 0)
        {
            break;
        }

        g_TaskMutex.lock();

        Task T = g_TaskList.at(0);
        g_TaskList.erase(g_TaskList.begin());
        g_TaskMutex.unlock();

        CalCulatePrime(T);
        qDebug() << "ThreadID " << currentThreadId() << 
            " Start: " << T.m_StartValue << 
            " End: " << T.m_EndValue << 
            " MinResult: " << T.m_MinResultValue << 
            " MaxResult: " << T.m_MaxResultValue << 
            " SumResult: " << T.m_SumResultValue;

        g_TaskMutex.lock();
        g_TaskCount--;
        if (g_TaskCount == 0)
        {
            g_TaskFinished.wakeOne();
            g_TaskMutex.unlock();
            break;
        }
        g_TaskMutex.unlock();

    }

}


main.cpp

#include "WorkerThread.h"

#include <QtCore/QCoreApplication>

QVector<Task> g_TaskList;
QWaitCondition g_TaskStart;
QWaitCondition g_TaskFinished;
QMutex       g_TaskMutex;
int          g_TaskCount;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WorkerThread Thread[8];

    for (int i = 0; i < 8; i++)
    {
        Thread[i].start();
    }

    for (int i = 0; i < 50; i++)
    {
        Task T;
        T.m_StartValue = i * 1000;
        T.m_EndValue = (i + 1) * 1000 * 100;
        g_TaskList.push_back(T);
    }
    g_TaskCount = g_TaskList.size();

    g_TaskStart.wakeAll();

    g_TaskMutex.lock();
    while(g_TaskCount > 0)
    {
        g_TaskFinished.wait(&g_TaskMutex);
    }
    g_TaskMutex.unlock();

    for (int i = 0; i < 8; i++)
    {
        Thread[i].wait();
    }

    qDebug() << "Finished" << "\n";

    return a.exec();
}
运行截图

展开阅读全文

没有更多推荐了,返回首页