今天碰到个问题:批量下载十几万张图片、且分散在很多网站上。
迅雷、FlashGet都有导入URL列表,然后批量下载的功能。但URL上万以后,速度很慢,界面几乎无响应甚至异常退出。最大任务数才几十,不给力。而图片文件又很小,单个文件不值得再多线程下载了。所以用下载工具不合适。
单下一张图片时,时间都是秒级的。系统所在SSD的IOPS大约50000,估计来几千个线程也能HOLD住。于是写了个C++程序,开300个线程,每线程再用system函数调用wget下载(中间还要经过cmd.exe去调用,实际是600个进程)。效果还不错。
正下得起劲时,看日志发现个缺陷:同一网站的内容随机分给多个wget,导致频繁重连,费了不少时间。给每个wget进程的URL最好在相同域上,又想出个办法:写段脚本把URL按域分成几百份,每个wget一份名单,照着下去,既快又简单。
(先前的程序就当是做多线程的习题了)
另:中间想改进时,杀掉了主程序。但任务管理器中看,系统还有几百个 cmd.exe 进程。手工删了几十个,烦了。linux有killall,Windows呢?……搜了下,有对应的:
- tasklist 查看所有进程
- tasklist /fi "imagename eq cmd.exe" 列出所有叫“cmd.exe”的进程。
- taskkill /fi "imagename eq cmd.exe" /f 杀掉所有叫“cmd.exe”的进程。世界清静了……