明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 666|回复: 2

多线程的学习应用1

[复制链接]
发表于 2020-5-27 20:58 | 显示全部楼层 |阅读模式

int main3()
{
        printf("\n 随机数: %f", LcCpuTime::MinToMaxRand(-3.112, 5.78, 5));
        system("pause");
}



int main4()
{
        //创建初始化线程
        std::thread tread1(LcThread::PrintLc);

        //这样主线程就会等待tread1线程结束后再运行
        tread1.join();

        //现在是由tread1子线程输出的信息

        return 0;
}

//主线程与子线程互不影响
//主线程是不用等待子线程结束后再运行
//改造main4
int main5()
{
        //创建初始化线程
        std::thread tread1(LcThread::PrintLc);

        //这样主线程就会等待tread1线程结束后再运行
        tread1.detach();
        //再次编译会发现并没有输出任何内容
        //这是因为主线程执行太快,还没等tread1运行完就已经结束了,
        //tread1并没有机会把字符串输出到屏幕中
        //这里必须注意一个子线程tread1一旦被detach一次就不能在join了,
        //编译是没有问题,但会出现错误
        //解决方案是在join之前进行判断是否可以被join

        if (tread1.joinable())
        {
                tread1.join();
        }//这样程序就不会崩溃

        return 0;
}



//改造main5使得主线程执行for循环(或者其他操作),子线程执行输出PrintLc函数
int main6()
{
        //创建初始化线程
        std::thread tread1(LcThread::PrintLc);

        //这样主线程就会等待tread1线程结束后再运行
        tread1.detach();
       
        //主线程其他操作,本例执行for循环输出100次-3.112致5.78之间的随机数

        for (int i = 0; i < 100; i++)
        {
                printf("\n 随机数: %f", LcCpuTime::MinToMaxRand(-3.112, 5.78, 5));
        }

        if (tread1.joinable())
        {
                tread1.join();
        }

        //这样的代码并不安全,假如for循环中抛出异常的话
        //那么ttread1在join之前就会被销毁
        //所以在循环输出之前必须先捕获异常
        //解决方案见main6

        return 0;
}
/*
子线程输出:老仓测绘上班记QQ:729292370

主线程输出:
        随机数 : -0.419720
        随机数 : -1.224970
        随机数 : 1.724700
        随机数 : -1.392750
        随机数 : -2.045180
        随机数 : -0.818800
        随机数 : 2.592070
        随机数 : -1.176560
        随机数 : 3.673170
        随机数 : 2.951940
        随机数 : 2.900870
        随机数 : -1.663890
        随机数 : 1.678740
        随机数 : -0.472950
        随机数 : 3.819250
        随机数 : 4.548850
        随机数 : -1.145370
        随机数 : -2.906980
        随机数 : 2.777950
        随机数 : 2.077680
        随机数 : -2.632610
        随机数 : 4.234190
        随机数 : 0.474680
....
*/


int main7()
{
        //创建初始化线程
        std::thread tread1(LcThread::PrintLc);

        //这样主线程就会等待tread1线程结束后再运行
        tread1.detach();
       
        //捕获异常
        try
        {
                //主线程其他操作,本例执行for循环输出100次-3.112致5.78之间的随机数
                for (int i = 0; i < 100; i++)
                {
                        printf("\n 随机数: %f", LcCpuTime::MinToMaxRand(-3.112, 5.78, 5));
                }
        }
        catch (...)//如果捕获异常
        {
                tread1.join();//执行
                throw;//抛出异常
        }
        //这样不管这段代码有没有抛出异常,都会执行子线程中的join,也就是输出子线程中的信息

        //一个线程不仅仅是可以通过函数进行构造,它还可以通过任何可被调用的对象来进行构造
        //继续改造

        return 0;
}


/*
//创建一个类来构造一个线程
class Fctor
{
public:
        void operator()()
        {
                //主线程其他操作,本例执行for循环输出100次-3.112致5.78之间的随机数
                for (int i = 0; i < 100; i++)
                {
                        printf("\n 流水号: %d", i);
                }
        }
};
*/
//添加一个类来进行构造线程
//你将看到主线程与子线程交互运行
int main8()
{
        //创建初始化线程
        Fctor fct;
        std::thread tread1(fct);


        //这样主线程就会等待tread1线程结束后再运行
        tread1.detach();

        //捕获异常
        try
        {
                //主线程其他操作,本例执行for循环输出100次-3.112致5.78之间的随机数
                for (int i = 0; i < 100; i++)
                {
                        printf("\n 随机数: %f", LcCpuTime::MinToMaxRand(-3.112, 5.78, 5));
                }
        }
        catch (...)//如果捕获异常
        {
                tread1.join();//执行
                throw;//抛出异常
        }
        return 0;
}


/*...
流水号: 63
        流水号 : 64
        流水号 : 65
        流水号 : 66
        流水号 : 67
        随机数 : 0.375010
        流水号 : 68
        流水号 : 69
        流水号 : 70
        流水号 : 71
        流水号 : 72
        流水号 : 73
        流水号 : 74
        流水号 : 75
        流水号 : 76
        流水号 : 77
        流水号 : 78
        流水号 : 79
        流水号 : 80
        流水号 : 81
        随机数 : 1.103000
        流水号 : 82
        流水号 : 83
        流水号 : 84
        流水号 : 85
        流水号 : 86
        流水号 : 87
        流水号 : 88
        流水号 : 89
        流水号 : 90
        流水号 : 91
        流水号 : 92
        流水号 : 93
        流水号 : 94
        随机数 : 3.850780
        流水号 : 95
        流水号 : 96
        流水号 : 97
        流水号 : 98
        流水号 : 99
        随机数 : -1.263310
        随机数 : -1.291460
        随机数 : 0.389750
        随机数 : 1.754550
        随机数 : 3.583730
        随机数 : -1.251950
        随机数 : 5.639150
        随机数 : 0.667040
        ....
*/



//添加一个类来进行构造线程(另一种用法,两种用法完全等效)
//你将看到主线程与子线程交互运行
int main()
{
        //创建初始化线程

        std::thread tread1((Fctor()));//


        //这样主线程就会等待tread1线程结束后再运行
        tread1.detach();

        //捕获异常
        try
        {
                //主线程其他操作,本例执行for循环输出100次-3.112致5.78之间的随机数
                for (int i = 0; i < 100; i++)
                {
                        printf("\n 随机数: %f", LcCpuTime::MinToMaxRand(-3.112, 5.78, 5));
                }
        }
        catch (...)//如果捕获异常
        {
                tread1.join();//执行
                throw;//抛出异常
        }
        return 0;
}

设想通过这种方式比如CAD中有几十万大量的数据要处理,那么我们可以新建一个子线程从一开始就让它先执行处理数据,主线程执行其他操作,预知后续如何请看下回分解

发表于 2020-5-29 00:48 | 显示全部楼层
老苍老师越来越牛了
 楼主| 发表于 2020-5-29 17:34 来自手机 | 显示全部楼层
你就别折煞我了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-27 13:00 , Processed in 0.374310 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表