首页 新闻 会员 周边 捐助

一千多个URL怎么实现同时用多个线程根据url下载页面源码?

0
悬赏园豆:120 [已解决问题] 解决于 2015-08-12 14:07

  现在有很多个URL(假设有一千多个),要根据这些url分别把他们对应的页面源码给下载下来。原先用了个单线程的,速度有点慢。老板说要用多线程同时操作,并把结果返回给住进程,再依次操作?那么,这几个多线程该怎么做?利用线程池?请各位好心人帮帮忙,有代码就更好了,万分感谢。C++。

Devinvow的主页 Devinvow | 初学一级 | 园豆:96
提问于:2015-08-05 17:01
< >
分享
最佳答案
0

1。5个List<url,desc> 集合,一个主集合,4个副集合;线程也建立5个线程

2.开启监听事件,当4个副集合有内容时,开启主线程,并把内容放到主线程对应的list集合里面,并处理业务逻辑,然后关闭主线程(或者让主线程休息一段时间,在处理业务逻辑)

收获园豆:20
唯我独萌 | 小虾三级 |园豆:537 | 2015-08-06 08:27

原理貌似挺好。window编程的话,有类似linux下的epoll或者select的监听函数吗?我再理一下思路,您看对不对哈?建立五个容器(在线程中用到的容器,是不是应该设置成全局的??),然后将url平均分别分派给这几个线程,各个线程开始处理事件,每处理一个加到各自的容器中,主线程等待线程处理完毕,然后把这些容器里的内容集中起来处理?您看对吗?

Devinvow | 园豆:96 (初学一级) | 2015-08-06 09:42

@Devinvow:这样也可以,但是经理或老板想要的是高效率且时间用的最少,你这种方法是最后用一个主线程汇总其他4个线程的数据,跟一个线程处理数据是差不多的。

唯我独萌 | 园豆:537 (小虾三级) | 2015-08-06 09:46

@背叛的冲刷: 额。。我就是按照您说得那个思路总结的。。估计是我理解错了。请您详细的讲解一下您的实现方法,包括怎么把线程里的数据返回给主线程?谢谢。。

Devinvow | 园豆:96 (初学一级) | 2015-08-06 09:53
其他回答(8)
-4

线程书上有,看书去。

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-08-05 17:06
1

利用线程池,你已经知道答案了

虔城墨客 | 园豆:185 (初学一级) | 2015-08-05 17:21

  额。。那个,我也仅仅知道线程池的原理。但还不知怎么应用到项目中?请问线程池是还得写还是从网上下载源码改改直接用就可以了?谢谢。

支持(0) 反对(0) Devinvow | 园豆:96 (初学一级) | 2015-08-06 09:26
0

把URL分成几份,多个线程同时去下载,和你一个线程差不多呀

稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-05 17:23

是效率差不多还是做法差不多?用不用利用什么线程池?

支持(0) 反对(0) Devinvow | 园豆:96 (初学一级) | 2015-08-05 17:25

@Devinvow: 是做法一样,不是效率,就和你计算机多核多线程一样的,你都知道用线程了,就已经实现90%了

支持(0) 反对(0) 稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-05 17:28

@稳稳的河: 谢谢。我的主线程还想利用下载的结果进行下一步操作,请问怎么从线程返回结果给主线程?还有就是,主线程怎么才能知道这几个线程全部执行完毕并等待它们?

支持(0) 反对(0) Devinvow | 园豆:96 (初学一级) | 2015-08-05 17:45

@Devinvow: 结果可以用全局变量,等待可以用handler.Wait();

 CountdownEvent handler = new CountdownEvent(100);
            for (int i = 0; i < 100; i++)
            {
                var j = i;
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    Console.WriteLine("thread " + j);
                    Thread.Sleep(1000);   //wait 1 seconds to do something
                    handler.Signal();
                });
            }

            handler.Wait();
            Console.WriteLine("finished");

 

支持(0) 反对(0) 稳稳的河 | 园豆:4216 (老鸟四级) | 2015-08-05 18:00
0

线程池是有效果的,是经过优化的。不信楼主可以试一下。

还有一个方案注是异步,其它楼主一千个url的处理,慢是慢在网络io吧。所以多线程效果不是很理像,你试试异步可能会好很多。

gw2010 | 园豆:1487 (小虾三级) | 2015-08-05 17:53

  额。。谢谢解答。还有那个,我也仅仅知道线程池的原理。但还不知怎么应用到项目中?请问线程池是还得写还是从网上下载源码改改直接用就可以了?谢谢。

支持(0) 反对(0) Devinvow | 园豆:96 (初学一级) | 2015-08-06 09:27
0

如果线程太多的话,还是不要每个URL开一个线程..

你试一下,100个线程去执行100个URL,比你用2个线程分别执行50个URL的速度慢很多...

我开始也以为线程越多执行越快,后来发现并不是这样的!

我曾经用100个线程做计算操作,要2分50多秒,后来我全把它们放一个线程中,只要1分10几秒.

hexllo | 园豆:318 (菜鸟二级) | 2015-08-05 19:42

嗯,是这样的,好像是根据每台机器的配置,所开的限制都不同。我记得哪个帖子上说过是cpu核心数*2+2是能优化的最大线程数量。具体没验证过。。

支持(0) 反对(0) Devinvow | 园豆:96 (初学一级) | 2015-08-06 09:28
0

用异步吧,在windows下用 完成端口,在Linux下用epoll ,当然也可以用线程池,其实异步也是用多线程,只是系统内核去做了

秋壶冰月 | 园豆:5903 (大侠五级) | 2015-08-05 21:00

额。。谢谢解答,只是我也仅仅知道线程池的原理。但还不知怎么应用到项目中?请问线程池是还得写还是从网上下载源码改改直接用就可以了?谢谢。

支持(0) 反对(0) Devinvow | 园豆:96 (初学一级) | 2015-08-06 09:29
0

好好学习下网络编程。

Devinvow | 园豆:96 (初学一级) | 2015-08-12 14:03
0

可以参考以上思路。另外多多看下侯捷的win32多线程程序设计,对你有帮助。

收获园豆:100
东子同学 | 园豆:64 (初学一级) | 2015-08-12 14:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册