多线程间的同步

 

串行解决方案示例代码:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QObject>
/*
sum(n)=> 1 + 2 + 3 + ..... + n
sum(1000)= ?
            [1,1000] = [1,300] + [301,600] + [601, 1000]
*/
class Calculator : public QObject
{
protected:
    int m_begin;
    int m_end;
    int m_result;
    void run()
    {
        qDebug() << objectName() << " run begin";
        for(int i=m_begin; i<=m_end; i++)
        {
            m_result += i;
        }
        qDebug() << objectName() << " run end";
    }
public:
    Calculator(int begin,int end)
    {
        m_begin = begin;
        m_end = end;
        m_result = 0;
    }
    void work()
    {
        run();
    }
    int result()
    {
        return m_result;
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main begin()" ;
    int sum = 0;
    Calculator c1(1,300);
    Calculator c2(301,600);
    Calculator c3(601,1000);
    c1.setObjectName("c1");
    c2.setObjectName("c2");
    c3.setObjectName("c3");
    c1.work();
    c2.work();
    c3.work();
    sum = c1.result() + c2.result() + c3.result();
    qDebug() << "sum = " << sum;
    qDebug() << "main end()";
    return a.exec();
}
从打印结果看,c1先运行,c2再运行,最后c3再运行。这种串行解决方案完全可以解决求和问题,但是太低效了。
编程实验:求和新解法——并行方案的代码示例:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
/*
sum(n)=> 1 + 2 + 3 + ..... + n
sum(1000)= ?
            [1,1000] = [1,300] + [301,600] + [601, 1000]
*/
class Calculator : public QThread
{
protected:
    int m_begin;
    int m_end;
    int m_result;
    void run()
    {
        qDebug() << objectName() << " run begin";
        for(int i=m_begin; i<=m_end; i++)
        {
            m_result += i;
            msleep(10);   //模拟在实际工程中可能产生耗时的行为
        }
        qDebug() << objectName() << " run end";
    }
public:
    Calculator(int begin,int end)
    {
        m_begin = begin;
        m_end = end;
        m_result = 0;
    }
    int result()
    {
        return m_result;
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main begin()" ;
    int sum = 0;
    Calculator c1(1,300);
    Calculator c2(301,600);
    Calculator c3(601,1000);
    c1.setObjectName("c1");
    c2.setObjectName("c2");
    c3.setObjectName("c3");
    c1.start();
    c2.start();
    c3.start();
    sum = c1.result() + c2.result() + c3.result();
    qDebug() << "sum = " << sum;
    qDebug() << "main end()";
    return a.exec();
}
从打印结果看,主线程先于子线程结束,c1,c2,c3这三个进程确实可以并行执行,执行速度也比串行解决方案快,但是执行结果却是错误的。为什么?
问题:线程间总是完全独立毫无依赖吗?
结论:在特殊情况下,多线程的执行在时序上存在依赖。

 

编程实验,并行计算初探
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
/*
sum(n)=> 1 + 2 + 3 + ..... + n
sum(1000)= ?
            [1,1000] = [1,300] + [301,600] + [601, 1000]
*/
class Calculator : public QThread
{
protected:
    int m_begin;
    int m_end;
    int m_result;
    void run()
    {
        qDebug() << objectName() << " run begin";
        for(int i=m_begin; i<=m_end; i++)
        {
            m_result += i;
            msleep(10);   //模拟在实际工程中可能产生耗时的行为
        }
        qDebug() << objectName() << " run end";
    }
public:
    Calculator(int begin,int end)
    {
        m_begin = begin;
        m_end = end;
        m_result = 0;
    }
    int result()
    {
        return m_result;
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main begin()" ;
    int sum = 0;
    Calculator c1(1,300);
    Calculator c2(301,600);
    Calculator c3(601,1000);
    c1.setObjectName("c1");
    c2.setObjectName("c2");
    c3.setObjectName("c3");
    c1.start();
    c2.start();
    c3.start();
    /*在这个地方主线程需要等待3个子线程执行结束,才能再执行*/
    c1.wait();
    c2.wait();
    c3.wait();
    sum = c1.result() + c2.result() + c3.result();
    qDebug() << "sum = " << sum;
    qDebug() << "main end()";
    return a.exec();
}
效率提高了,运行结果也完全正确。
看一下wait函数的介绍,在linux编程中,这个函数类似于pthread_join()


    
    
            

 

串行解决方案示例代码:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QObject>
/*
sum(n)=> 1 + 2 + 3 + ..... + n
sum(1000)= ?
            [1,1000] = [1,300] + [301,600] + [601, 1000]
*/
class Calculator : public QObject
{
protected:
    int m_begin;
    int m_end;
    int m_result;
    void run()
    {
        qDebug() << objectName() << " run begin";
        for(int i=m_begin; i<=m_end; i++)
        {
            m_result += i;
        }
        qDebug() << objectName() << " run end";
    }
public:
    Calculator(int begin,int end)
    {
        m_begin = begin;
        m_end = end;
        m_result = 0;
    }
    void work()
    {
        run();
    }
    int result()
    {
        return m_result;
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main begin()" ;
    int sum = 0;
    Calculator c1(1,300);
    Calculator c2(301,600);
    Calculator c3(601,1000);
    c1.setObjectName("c1");
    c2.setObjectName("c2");
    c3.setObjectName("c3");
    c1.work();
    c2.work();
    c3.work();
    sum = c1.result() + c2.result() + c3.result();
    qDebug() << "sum = " << sum;
    qDebug() << "main end()";
    return a.exec();
}
从打印结果看,c1先运行,c2再运行,最后c3再运行。这种串行解决方案完全可以解决求和问题,但是太低效了。
编程实验:求和新解法——并行方案的代码示例:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
/*
sum(n)=> 1 + 2 + 3 + ..... + n
sum(1000)= ?
            [1,1000] = [1,300] + [301,600] + [601, 1000]
*/
class Calculator : public QThread
{
protected:
    int m_begin;
    int m_end;
    int m_result;
    void run()
    {
        qDebug() << objectName() << " run begin";
        for(int i=m_begin; i<=m_end; i++)
        {
            m_result += i;
            msleep(10);   //模拟在实际工程中可能产生耗时的行为
        }
        qDebug() << objectName() << " run end";
    }
public:
    Calculator(int begin,int end)
    {
        m_begin = begin;
        m_end = end;
        m_result = 0;
    }
    int result()
    {
        return m_result;
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main begin()" ;
    int sum = 0;
    Calculator c1(1,300);
    Calculator c2(301,600);
    Calculator c3(601,1000);
    c1.setObjectName("c1");
    c2.setObjectName("c2");
    c3.setObjectName("c3");
    c1.start();
    c2.start();
    c3.start();
    sum = c1.result() + c2.result() + c3.result();
    qDebug() << "sum = " << sum;
    qDebug() << "main end()";
    return a.exec();
}
从打印结果看,主线程先于子线程结束,c1,c2,c3这三个进程确实可以并行执行,执行速度也比串行解决方案快,但是执行结果却是错误的。为什么?
问题:线程间总是完全独立毫无依赖吗?
结论:在特殊情况下,多线程的执行在时序上存在依赖。

 

编程实验,并行计算初探
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
/*
sum(n)=> 1 + 2 + 3 + ..... + n
sum(1000)= ?
            [1,1000] = [1,300] + [301,600] + [601, 1000]
*/
class Calculator : public QThread
{
protected:
    int m_begin;
    int m_end;
    int m_result;
    void run()
    {
        qDebug() << objectName() << " run begin";
        for(int i=m_begin; i<=m_end; i++)
        {
            m_result += i;
            msleep(10);   //模拟在实际工程中可能产生耗时的行为
        }
        qDebug() << objectName() << " run end";
    }
public:
    Calculator(int begin,int end)
    {
        m_begin = begin;
        m_end = end;
        m_result = 0;
    }
    int result()
    {
        return m_result;
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main begin()" ;
    int sum = 0;
    Calculator c1(1,300);
    Calculator c2(301,600);
    Calculator c3(601,1000);
    c1.setObjectName("c1");
    c2.setObjectName("c2");
    c3.setObjectName("c3");
    c1.start();
    c2.start();
    c3.start();
    /*在这个地方主线程需要等待3个子线程执行结束,才能再执行*/
    c1.wait();
    c2.wait();
    c3.wait();
    sum = c1.result() + c2.result() + c3.result();
    qDebug() << "sum = " << sum;
    qDebug() << "main end()";
    return a.exec();
}
效率提高了,运行结果也完全正确。
看一下wait函数的介绍,在linux编程中,这个函数类似于pthread_join()












