![]() | 1 realityone 2015-07-07 20:28:15 +08:00 你在 q 里面再加一句 time.sleep(5) 然后观察下就知道问题在哪里了 `t.join()` |
![]() | 2 RichardZhiming 2015-07-07 20:32:02 +08:00 via Android 尽量使用多进程,gil是Python的历史遗留问题 |
3 latteczy OP @RichardZhiming 嗯,只是想搞明白这个Python的多线程是怎么回事 |
4 zhyu 2015-07-07 20:36:55 +08:00 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 latteczy OP @realityone 加上time.sleep(5)之后结果是21秒多,还是不太明白,麻烦能否再指点一下。是t.join()有问题么? |
![]() | 7 Shazoo 2015-07-07 20:43:33 +08:00 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() 这样应该会快些。 |
![]() | 8 onlyice 2015-07-07 20:47:35 +08:00 |
![]() | 9 alexapollo 2015-07-07 20:56:35 +08:00 建议你用多进程 multiprocessing 模块。 python 的线程机制比较弱,一般用多进程或异步解决这个问题。 |
10 latteczy OP @alexapollo 我知道,我只是想弄明白Python的多线程是怎么回事。而且对于这段代码,多线程应该是会有效率上的提高的,但是我并没测试出有提高。所以想弄明白是怎么回事。 |
![]() | 11 alexapollo 2015-07-07 21:08:03 +08:00 @latteczy GIL,查了就懂了。活用google,SO上这种问题蛮多的 |
12 latteczy OP @alexapollo 嗯,这段代码效率没提高就是楼上所说的t.join()位置不对。主要原因不在GIL吧 |
![]() | 13 alexapollo 2015-07-07 21:22:53 +08:00 @latteczy 恩,是的 |
![]() | 14 est 2015-07-07 21:27:07 +08:00 GIL 真是个活靶子。 |
15 latteczy OP @Shazoo 感谢!确实是这样。但是又有个问题是代码改正以后貌似没法统计运行时间了。。 https://gist.github.com/smartczy/35e692064b775dcc3e17#comment-1487649 |
![]() | 16 uniquecolesmith 2015-07-07 21:44:00 +08:00 gevent 用起来 |
![]() | 17 aec4d 2015-07-07 22:06:43 +08:00 这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 你可以试着不加看是什么样的。等你熟悉了之后你就晓得那时候该用这些 哪时候不该用 |
![]() | 20 fanta 2015-07-08 09:32:06 +08:00 aec4d 说的对,每个连接是0.7s时,问题已不是多线程的问题了, 是网络(服务器链路)问题. |
![]() | 21 Shazoo 2015-07-08 10:08:30 +08:00 |
23 yuyang 2015-07-08 14:54:33 +08:00 @aec4d 网上一票SB只要看到别人用python写多线程程序,立马就喷,立马搬出GIL,立马要你改成多进程,以前我还会吐槽下这些不懂装懂的家伙,现在直接无视.. |
24 sampeng 2015-07-08 16:43:55 +08:00 不是所有的多线程一定带来效益的提升。。。。。尤其是里面有网络请求这样的东西的时候。 线程同步会坑很大一堆时间,完全和多线程带来的收益抵消甚至更严重的问题。 个人看法,多线程只用在相互之间毫无关系,一丁点关系都没有。不需要同步状态。没有顺序关联的时候是最有效的。其他时候,纯粹是自己给自己找麻烦(线程同步很蛋疼的) |
![]() | 27 qqblog 2015-07-11 14:26:33 +08:00 计划今后生产、开发环境换成pypy,版本未定 |