好久之前就想写一篇关于python多线程和多进程的文章,顺便总结一下。
由于python全局锁GIL的存在,python本身是不支持真正意义上的多线程的,但是python依旧提供了一个thread模块,以便开发者使用多线程,在当开发过程中,如果很多操作与IO相关的,就可以使用该模块或者该模块的高级版本threading,具体使用方法网上有很多,这里推荐使用threading模块,因为这个模块便于控制每个线程,而且相对容易编写。
这里是一个栗子:
import threading
def thread_fun(num):
for n in range(0, int(num)):
print " I come from %s, num: %s" %( threading.currentThread().getName(), n)
def main(thread_num):
thread_list = list();
# 先创建线程对象
for i in range(0, thread_num):
thread_name = "thread_%s" %i
thread_list.append(threading.Thread(target = thread_fun, name = thread_name, args = (20,)))
# 启动所有线程
for thread in thread_list:
thread.start()
# 主线程中等待所有子线程退出
for thread in thread_list:
thread.join()
if __name__ == "__main__":
main(3)
也有人推荐使用multiprocessing模块来进行多进程开发,使用起来也非常方便,这里有一个demo:
#!/usr/bin/env python
from multiprocessing import Process
import os
import time
def sleeper(name, seconds):
print 'starting child process with id: ', os.getpid()
print 'parent process:', os.getppid()
print 'sleeping for %s ' % seconds
time.sleep(seconds)
print "Done sleeping"
if __name__ == '__main__':
print "in parent process (id %s)" % os.getpid()
p = Process(target=sleeper, args=('bob', 5))
p.start()
print "in parent process after child process start"
print "parent process about to join child process"
p.join()
print "in parent process after child process join"
print "parent process exiting with id ", os.getpid()
print "The parent's parent process:", os.getppid()
DUANG DUANG DUANG 看到了,然后忘了上面的吧。
在后来我突然意识到一点,像python这种脚本程序完全没有必要在程序内使用多进程或者多线程。因为我们完全可以多开程序!
两年前我自己用tornado写过一个博客,挂上去就是开了两个tornado程序,添加上nginx和守护程序,一切妥妥的,完全不需要在程序里面使用多线程。如果需要多线程开发,完全可以将任务分给几个程序,挨个打开就行了。
P.S 当然,如果要编写一个下载器或者什么的,还是要使用并行技术,这里有一个选择的顺序:程序多开 > 多进程 > 多线程,多线程和多进程如果要输出什么东西还要考虑锁的问题,特别是在使用sqlite的时候,进程会遇到写入冲突,还有要使用queue模块,辅助线程之间通讯。