打广告网站,成都建设监理协会网站网址,门户网站开发技术服务合同,网站建设书一、多线程
多线程不管是在前面的文章分析中还是在网上还是大书籍上#xff0c;学习C/C多线程编程是无法绕过的#xff0c;即使使用别人封装好的框架#xff0c;包括使用STL的一些库#xff0c;如果仅仅是简单的应用#xff0c;可能也就过去了。不过#xff0c;稍微复杂…一、多线程
多线程不管是在前面的文章分析中还是在网上还是大书籍上学习C/C多线程编程是无法绕过的即使使用别人封装好的框架包括使用STL的一些库如果仅仅是简单的应用可能也就过去了。不过稍微复杂的一些应用其实就需要对多线程的应用有深层次的理解。 尤其在使用一些封装库时特别要注意库的一些注意事项往往这些注意点是应用BUG的重要原因。比如std::async中std::future返回值如果控制不好异步就可能变成了同步。所以说多线程要想写好不但要会用一些库一些API更要懂得这些库的底层原理直到这个库调用的不同的平台封装的是哪个OS的系统函数。如果再展开到并发和并行更得需要了解相关OS的相关进程线程的调度知识等等。这些都是写多线程的开发者需要一步步学习的目标。不过在这里只就时论事只讲多线程与OS相关的知识用到就展开分析一下。 这个系列更侧重于线程的应用而非基础知识的普及所以如果在示例的一些源码代码中不清楚的基础的用法需要去查一下前面的多线程的基础知识的文章或者自己行在网上查找一些相关知识。
二、线程的运用
多线程的应用其实是一个非常重要且普遍的应用。协程的编程目前看来应该是被排除到了更高的应用层上也就是说想用好协程更多的是纯上层应用了。线程被迁移到了一个中间层的库应用。说得再深入一些协程的普及可能会让开发者写并发变得简单但同样大幅降低了技术门槛这意味着什么以前不明白的这两年应该都懂了。 多线程的应用一般会和异步IO共同使用有的人在网上说多线程和异步有什么不同这就说汽车和钢铁有什么不同一样这本来就是两回事。说多了扯回来。 多线程的应用非常广泛图像处理、数据读写、IO通信和时间控制等等都可以用到。但正如已经分析过的一样用的方法不一样那么产生的结果也不一样。单纯的多线程读写操作不涉及到数据互斥没有什么难度。举个简单的例子写十个线程读十个不同的文件这和写普通的非线程代码没有本质不同可能只是套上了十个线程的壳子。但是如果这十个线程需要同时把读到数据写到一个缓冲区内根据不同情况来覆盖或者追加相关数据这就需要谨慎的处理了。否则数据很可能不是丢失就是多存储了。 另外如果只有五个线程来处理十个文件呢如果这十个文件大小不一有的非常大有的非常小那么小文件读取完成后这个线程不就空闲了么多线程不还是单线程么。再细分一下大文件可不可以切成段在别的线程读完成文件后去读这些分段的大文件来加速读取的速度呢这都是多线程需要解决的现实问题。 很多问题在学习多线程编程时是很难想到的或者说遇到实际问题不知道怎么下手这其实就是学无法致用的一个典型的表现。在这个系列中就把这些多线程的用法与实际的情况结合起来进行一一的分析。
三、例程
做为简单的开始本篇不做多么复杂的例程只是把刚刚提到std::async遇到的同步问题展现一下以及相关的处理办法
#include iostream
#include future
#include chronoint getData(int x) {std::cout async thread run start!std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(6000));std::cout async thread run end! std::endl;return x;
}int main()
{std::async(std::launch::async, getData, 100);std::cout go to ...std::endl;return 0;
}运行结果
async thread run start!
async thread run end!
go to ...
你会发现运行的结果并不是期房的两个线程并行执行而执行完async中的线程才回头执行主线程的函数。什么原因呢在std::async中有下面的话 “If the std::future obtained from std::async is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes, essentially making code such as the following synchronous” 在std::future的析构函数中 “these actions will not block for the shared state to become ready, except that they may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and the current object was the last reference to the shared state.” 在下面还有一句话意思是说只在运行策略为“ std::launch::async ”才会产生这种情况。 所以通过上述两个说明就明白了在std::async中std::future的临时变量会在没有被移动或者引用情况下一直阻塞到异步计算完成所以这句话也就给了解决方法
auto d std::async(std::launch::async, getData, 100);只需增加上面的返回值处理即可延长一下std::future的生命周期至期望的位置即可。用别人的东西就得服别人的套路一个不小心就会吃亏上当。不过话又说回来想省事吃点亏也应该对吧。
四、总结
从简单开始不忘初心朝着实际应用不断的前进。多线程编程属于那种入门容易写好难精通更难的一种编程技术真正的生产上大牛们被憋住当场打脸的情况也不少见。总之一句话多看书多实践多应用。小心写代码防御性编程少引入BUG比如事后调试定位要更容易做到一些。