作者回复: Thread是threading模块的一个用于创建线程的类,创建线程有两个方法,一个是通过继承Thread类,重写run方法;我在视频中演示的Mythread类就是这种方法了,要注意覆盖的是父类继承过来的run方法,start还是继承过来不变的。这里要注意的是start()和run() 是Thread的两种不同方法,官方定义在这里:https://docs.python.org/3.7/library/threading.html 那么把他们的解释翻译成中文就是 start() 开始线程工作,把run()方法放到一个另外的单独的线程里执行 ;run() 线程工作方法,在“当成”线程执行函数里面的代码。 所以他们的作用一个是开启新线程,一个是按照线程的方式执行程序。我们可以写个小程序来验证一下 import threading from threading import current_thread class Mythread(threading.Thread): def run(self): print(current_thread().getName()) t1 = Mythread() t1.run() t1.start() 这段程序的执行结果是: MainThread Thread-1 也就是说单独运行run()方法,会把主进程当做一个线程来看,执行的代码空间在MainThread主线程中,执行了start()方法,python会新创建一个线程,叫Thread-1,然后再去调用run()来运行,这就是他们两个的区别了。
作者回复: 做这样一个实验,thread.join()这条语句放在for循环中,放在for循环外(即这条语句前面没有空格),注释这条语句,观察一下输出有什么变化?你能解释三种变化的原因吗?
作者回复: 实现的方法还是很多的,我介绍一种主流的方法给你,其实你也意识到从主页到下一级页面的不可拆解,其实是不需要将他们都进行多线程化的,多线程的目的是充分发挥爬虫主机的性能,和充分利用上传下载带宽不对等的空闲时间。 可以考虑将获取需要下载游记的url作为一个方法,将这个方法多线程化,并发的获取url之后,将url存入一个临时的空间,再使用一个方法根据得到的url多线程化去请求网页并下载,既保证了采集url和下载的并发,又实现了异步,是不是设计的非常好?当然咱们同学也不用自己再开发这样的工具,有一个非常知名的爬虫框架叫做Scrapy就实现了这个功能,如果对多线程爬虫感兴趣建议学习一下这个框架和阅读它的例子
作者回复: 最多线程由两方面决定:内存容量和软件限制。 虽然线程是轻量级进程,但是创建线程也是要消耗内存的,初始状态下消耗打小就是内存栈了,每创建一个线程为其分配一个线程栈; 还有一种限制是系统的配置参数限制,比如在linux上 每进程默认创建线程是1024个,在local_lim.h中定义。可以使用ulimt -a查看线程栈大小
作者回复: 赞!
作者回复: 1 “可能”在 5 6 之前结束, 因为多线程是并发执行,没有限制它何时结束自己 2 “可能”在5 6 之后结束,但是显示在了前面,因为产生结果是并行的,但是终端显示一定是串行的
作者回复: 您好,由于是多线程程序,输出内容不按顺序显示是正常现象
作者回复: 默认的run 是没有任何功能的, 你只有重写了run才能通过多线程实现你的功能啊, threading 模块是实现了多线程的框架,需要多线程做什么事情,要在run里面实现
作者回复: 1 join的例子因为刚接触到join()所以没有写比较复杂的例子,只是介绍了语法和功能,所以在用该示例代码时显得“join没啥用”,那么我提供一个父进程用作daemon进程的例子,将上面的程序稍作更改,这次启动多个线程你可以将join所在的for循环注释,就能对比出差别了,代码如下: import threading import time def run(): time.sleep(5) print('sub thread', threading.current_thread().name) time.sleep(2) if __name__ == '__main__': print('main thread start', threading.current_thread().name) thread_list = [] for i in range(5): t = threading.Thread(target=run) thread_list.append(t) for t in thread_list: t.setDaemon(True) t.start() for t in thread_list: t.join() print('main thread stop' , threading.current_thread().name)
作者回复: 写单个文件,是不能使用多线程的,一个是顺序错乱,另一个是一个文件进行多线程写不会加快写入速度。正确的做法是 1 使用raid技术加快磁盘读写速度,或者使用固态硬盘替代传统磁盘。 2 使用数据库,实现数据的并发写入