一、进程
1)创建方法
1、通过 os 模块中的 fork 方式实现多进程
调用 fork() 放回俩次,原因在于操作系统将当前进程(父进程)复制出来一份进程(子进程),这两个进程几乎完全相同。但是
fork 在父进程中返回 的是子进程的ID,
在子进程中返回 永远是 0。
#coding=utf-8
import os
print 'current Process (%s) start ...'%(os.getpid())
pid = os.fork()
if pid < 0:
print 'error in fork'
elif pid == 0:
print '子进程是(%s),父进程是(%s)',(os.getpid(),os.getppid())
else:
print '我(%s)创建了一个子进程(%s)',(os.getpid(),pid)
输出结果是:
2、使用 multiprocessing 模块创建
使用该模块中的 Process 类对象 创建子进程。同时调用类的 start() 和 join() 来实现 启动进程 和 进程间的同步。
#encoding=utf-8
import os
from multiprocessing import Process
#子进程要执行的代码
def run_proc(name):
print "我是子进程 %s (%s) Running..." %(name,os.getpid())
if __name__ == '__main__':
print '父进程 (%s)' %(os.getpid())
for i in range(5):
p = Process(target=run_proc,args=((i),))
print '开始启动。。。'
p.start()
p.join()
print '结束。。。。'
运行结果:
3.使用 multiprocessing 模块的Pool 创建
可以控制线程的个数。
#coding=utf-8
import os,time,random
from multiprocessing import Pool
def run_task(name):
print '子进程 %s (pid = %s) 正在运行' %(name,os.getpid())
time.sleep(random.random()*3)
print '子进程 %s 结束' %name
if __name__ == '__main__':
print '父进程 %s.' %os.getpid()
p = Pool(processes=3)
for i in range(5):
p.apply_async(run_task,args=(i,))
print '正在等待所有的线程完成。。'
p.close()
p.join()
print '完成所有的子进程。 '
结果:
看到先运行3个线程,然后等待完成后,再创建下一个线程。
二、线程
1)用 threading 模块创建多线程
#coding=utf-8
import time,threading
import random
#新线程执行的代码
def thread_run(urls):
print 'Current %s is running...' % threading.current_thread().name
for url in urls:
print '%s -------->>>>>> %s'%(threading.current_thread().name, url)
time.sleep(random.random())
print '%s ended.' % threading.current_thread().name
print '%s is running...' % threading.current_thread().name
t1 = threading.Thread(target=thread_run, name='Thread_1', args=(['url_1', 'url_2', 'url_3'],))
t2 = threading.Thread(target=thread_run, name='Thread_2', args=(['url_4', 'url_5', 'url_6'],))
t1.start()
t2.start()
t1.join()
t2.join()
print '%s is ended...' % threading.current_thread().name
运行结果
2)使用 threading.Thread 继承创建线程类
#coding=utf-8
import time,threading
import random
#新线程执行的代码
def thread_run(urls):
print 'Current %s is running...' % threading.current_thread().name
for url in urls:
print '%s -------->>>>>> %s'%(threading.current_thread().name, url)
time.sleep(random.random())
print '%s ended.' % threading.current_thread().name
print '%s is running...' % threading.current_thread().name
t1 = threading.Thread(target=thread_run, name='Thread_1', args=(['url_1', 'url_2', 'url_3'],))
t2 = threading.Thread(target=thread_run, name='Thread_2', args=(['url_4', 'url_5', 'url_6'],))
t1.start()
t2.start()
t1.join()
t2.join()
print '%s is ended...' % threading.current_thread().name
运行结果:
注意 线程同步问题 acquire() release() 使用
三、协程
from gevent import monkey; monkey.patch_all()
import gevent
import urllib2
def run_task(url):
print 'Visit -->>%s' %url
try:
response = urllib2.urlopen(url)
data = response.read()
print '%d bytes received from %s.' %(len(data),url)
except Exception,e:
print e
if __name__ == '__main__':
urls=['https://github.com/','https://www.python.org/','https://www.jd.com/']
#形成协程
greenlets = [gevent.spawn(run_task,url) for url in urls]
#添加协程任务,并且启动运行
gevent.joinall(greenlets)
结果:
注意:1、3个网络操作是并发执行的,结束顺序是不同的,但其实只有一个线程。
2、from gevent import monkey; monkey.patch_all() 一定要添加,启动过程中通过monkey patch 完成。
2)使用 Pool 对象来管理创建协程
from gevent import monkey; monkey.patch_all()
from gevent.pool import Pool
import urllib2
def run_task(url):
print 'Visit -->%s' %url
try:
response = urllib2.urlopen(url)
data = response.read()
print '%d bytes received from %s.' % (len(data), url)
except Exception,e:
print e
return 'url:%s ---->> finish' %url
if __name__ == '__main__':
pool = Pool(2)
urls=['https://github.com/','https://www.python.org/','https://www.jd.com/']
results = pool.map(run_task,urls)
print results
运行结果:
是通过书本学习的,然记录一下。