上面的代码分别用多线程和普通方式抓取页面信息。但是二者运行时间相差无几,大约都是0.7+秒。这里应该不是CPU密集型,所以多线程应该有效率的提高才对。不知是何原因?
最近在学习Python的多线程,请大神多多指教!
|
realityoneJul 7, 2015
1
你在 q 里面再加一句 time.sleep(5) 然后观察下就知道问题在哪里了
`t.join()` |
|
RichardZhimingJul 7, 2015 via Android
2
尽量使用多进程,gil是Python的历史遗留问题
|
|
3
@RichardZhiming 嗯,只是想搞明白这个Python的多线程是怎么回事
|
|
zhyuJul 7, 2015
4
join([timeout])
Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception – or until the optional timeout occurs. |
|
5
@realityone 加上time.sleep(5)之后结果是21秒多,还是不太明白,麻烦能否再指点一下。是t.join()有问题么?
|
|
ShazooJul 7, 2015
7
threads = []
for i in range(4): t = threading.Thread(target=q, args=(hosts[i],)) threads.append(t) t.start() for t in threads: t.join() 这样应该会快些。 |
|
alexapolloJul 7, 2015
9
建议你用多进程 multiprocessing 模块。
python 的线程机制比较弱,一般用多进程或异步解决这个问题。 |
|
10
@alexapollo 我知道,我只是想弄明白Python的多线程是怎么回事。而且对于这段代码,多线程应该是会有效率上的提高的,但是我并没测试出有提高。所以想弄明白是怎么回事。
|
|
alexapolloJul 7, 2015
11
@latteczy GIL,查了就懂了。活用google,SO上这种问题蛮多的
|
|
12
@alexapollo 嗯,这段代码效率没提高就是楼上所说的t.join()位置不对。主要原因不在GIL吧
|
|
alexapolloJul 7, 2015
13
@latteczy 恩,是的
|
|
estJul 7, 2015
14
GIL 真是个活靶子。
|
|
15
@Shazoo 感谢!确实是这样。但是又有个问题是代码改正以后貌似没法统计运行时间了。。
https://gist.github.com/smartczy/35e692064b775dcc3e17#comment-1487649 |
|
uniquecolesmithJul 7, 2015
16
gevent 用起来
|
|
aec4dJul 7, 2015
17
这TM关GIL毛事 简直躺枪
要记住 断然给你提GIL的 要么是高手 要么是SB 有GIL还有multiprocessing呢 多线程最需要注意的应该是线程安全 这是threading.join的文档 join([timeout]) Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception – or until the optional timeout occurs. When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call isAlive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out. When the timeout argument is not present or None, the operation will block until the thread terminates. A thread can be join()ed many times. join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception. 看了之后你就发现 在上面加上t.join就和下面遍历的写法实质上是一模一样的. 一般网上很多教程给你加上setDaemon 加上join 你可以试着不加看是什么样的。等你熟悉了之后你就晓得那时候该用这些 哪时候不该用 |
|
fantaJul 8, 2015
20
aec4d 说的对,每个连接是0.7s时,问题已不是多线程的问题了, 是网络(服务器链路)问题.
|
|
yuyangJul 8, 2015
23
@aec4d 网上一票SB只要看到别人用python写多线程程序,立马就喷,立马搬出GIL,立马要你改成多进程,以前我还会吐槽下这些不懂装懂的家伙,现在直接无视..
|
|
sampengJul 8, 2015
24
不是所有的多线程一定带来效益的提升。。。。。尤其是里面有网络请求这样的东西的时候。
线程同步会坑很大一堆时间,完全和多线程带来的收益抵消甚至更严重的问题。 个人看法,多线程只用在相互之间毫无关系,一丁点关系都没有。不需要同步状态。没有顺序关联的时候是最有效的。其他时候,纯粹是自己给自己找麻烦(线程同步很蛋疼的) |
|
qqblogJul 11, 2015
27
计划今后生产、开发环境换成pypy,版本未定
|