找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 699|回复: 1

[分享] 多线程的学习应用1

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

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

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中有几十万大量的数据要处理,那么我们可以新建一个子线程从一开始就让它先执行处理数据,主线程执行其他操作,预知后续如何请看下回分解

评分

参与人数 1D豆 +5 收起 理由
newer + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 10个

财富等级: 恭喜发财

发表于 2020-9-22 19:59:31 | 显示全部楼层
thank your code
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-21 23:03 , Processed in 0.425631 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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