多线程间的同步

Posted -glb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程间的同步相关的知识,希望对你有一定的参考价值。

技术图片

 

 技术图片

 

串行解决方案示例代码:

#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()

技术图片

技术图片

 

以上是关于多线程间的同步的主要内容,如果未能解决你的问题,请参考以下文章

第七十四课多线程间的同步

多线程---线程间的通信

java基础入门-多线程同步浅析-以银行转账为样例

C#多线程间的同步问题

多线程(02)

JAVA多线程之线程间的通信方式