多任务的实现有3种方式:
- 多进程模式;
- 多线程模式;
- 多进程+多线程模式。
多进程
Unix/Linux操作系统提供了一个fork()
系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()
调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。子进程永远返回0
,而父进程返回子进程的ID。
multiprocessing
模块就是跨平台版本的多进程模块
# from multiprocessing import Process # import os # def run_proc(name): # print('Run child process %s (%s)...' % (name, os.getpid()))#用.getpid()就可以拿到父进程的ID # if __name__=='__main__':#生成进程必须要有 # print('Parent process %s.' % os.getpid())#用.getpid()就可以拿到子进程的ID # p = Process(target=run_proc, args=('ww',)) #生成一个进程 target=run_proc调用函数, args=('test',)为函数添加参数 # print('Child process will start.') # p.start()#开始运行子进程 # p.join()#等待子进程运行结束 # print('Child process end.')
Pool
如果要启动大量的子进程,可以用进程池的方式批量创建子进程
# from multiprocessing import Pool # import os, time, random # def long_time_task(name): # print('Run task %s (%s)...' % (name, os.getpid()))#用.getpid()就可以拿到父进程的ID # start = time.time()#进程开始时间 # time.sleep(random.random() * 3)#休眠(随机数*3)秒 # end = time.time()#进程结束时间 # print('Task %s runs %0.2f seconds.' % (name, (end - start))) # if __name__=='__main__': # print('Parent process %s.' % os.getpid()) # p = Pool(4)#允许同时运行的进程 # for i in range(5): # p.apply_async(long_time_task, args=(i,))#生成进程 # print('Waiting for all subprocesses done...') # p.close()#开始运行子进程 # p.join()#等待运行的子进程结束 # print('All subprocesses done.')
多线程
进程是由若干线程组成的,一个进程至少有一个线程。
Python的线程是真正的Posix Thread,而不是模拟出来的线程。
# import time, threading # # 新线程执行的代码: # def loop(): # print('thread %s is running...' % threading.current_thread().name)#threading模块有个current_thread(),永远返回当前线程的实例,主线程实例的名字叫MainThread # n = 0 # while n < 5: # n = n + 1 # print('thread %s >>> %s' % (threading.current_thread().name, n)) # time.sleep(1)#使线程休眠1秒 # print('thread %s ended.' % threading.current_thread().name) # print('thread %s is running...' % threading.current_thread().name) # t = threading.Thread(target=loop, name='LoopThread')#生成一个线程 # t.start()#开始子线程 # t.join()#等待子线程结束 # print('thread %s ended.' % threading.current_thread().name)