二十八、python的多线程和多进程网络编程
线程和进程关系:
进程是具有独立功能的程序,进程是系统进行资源分配和调度的一个独立单位
线程是进程的一个实体,是cpu调度的基本单位,它是比进程更小的能独立运行的基本单位
国家是系统,企业是进程,个人是线程。
进程和线程:
进程有独立的地址空间,一个进程崩溃后,不会对其它进程产生影响(windows有点烂linux不会)。
线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。所以单进程的程序比多线程的程序健壮。
GIL和多线程:
Globle Interpreter Lock
CPU密集型
IO密集型
Python的多线程:
1、Thread模块:偏底层
2、Threading模块:偏高层
3、继承threading.Thread,实现run()方法
-join() : 挂起当前线程,直到被调用线程结束
-start():启动线程,执行run中的代码
-is.active():线程是否结束
线程中的锁:
threading.Lock
threading.Rock
Acquire(): 申请锁
Release():释放锁
代码1:
class A(threading.Thread):
def run(self):
while True:
print 'in thread' #多个输出在一行可证明print为非原子操作
time.sleep(1)
if __name__ == "__main__":
mt = [A() for i in range(4)]
for t in mt:
t.start()
for t in mt:
t.join()
代码二:
class A(threading.Thread):
def __init__(self, n):
threading.Thread.__init__(self) #必须要调用父类的这个方法,否则实例化失败
self._n = n
def run(self):
while True:
print 'in thread %s' % self._n #可以看到In threading是那个线程打印的
time.sleep(1)
if __name__ == "__main__":
mt = [A(i) for i in range(4)]
for t in mt:
t.start()
for t in mt:
t.join()
代码三:
from faker import Factory
faker = Factory.create()
cnt = 10000
x1 = [faker.paragraph() for i in range(cnt)]
x2 = [faker.paragraph() for i in range(cnt)]
import time
#1、单线程
start=time.clock()
for one in x1:
len(one)
for one in x2:
len(one)
end = time.clock()
print 'single thread is %s ' % (end-start)
代码三:
#2、多线程,线程多反而慢咯??cpu密集型的任务,py的多线程反而会适得其反。并没有磁盘i/o和网络i/o
import threading
class A(threading.Thread):
def __init__(self, x):
threading.Thread.__init__(self)
self.x = x
def run(self):
for each in self.x:
len(each)
t1 = A(x1)
t2 = A(x2)
start1 = time.clock()
t1.start()
t2.start()
t1.join()
t2.join()
end1 = time.clock()
print 'two thread is %s ' % (end1-start1)
print (end1-start1)/(end-start)
Python的多进程:
1、多个python进程=多个GIL锁
2、Multiprocessing模块
3、继承multiprocessing.Process,实现run()方法
-join(): 挂起当前进程,直到被调用进程结束
-start(): 启动进程,执行run中的代码
代码1:
import multiprocessing
import time
#1、多进程,运行后可以去任务列表中看到5个python.exe进程。为啥是5个?脚本一个,脚本里面启动4个
class A(multiprocessing.Process):
def __init__(self, n):
multiprocessing.Process.__init__(self) #必须要调用父类的这个方法,否则实例化失败
self._n = n
def run(self):
while True:
print 'in thread %s' % self._n #可以看到In threading是那个线程打印的
time.sleep(1)
if __name__ == "__main__":
mt = [A(i) for i in range(4)]
for t in mt:
t.start()
for t in mt:
t.join()
进程间通信:
1、进程的内存空间是相互独立的
2、通过multiprocessing.Queue实现通信
3、Queue.put()
4、Queue.get()
代码二:
##模拟进程之间的消息通信,生产者和消费者模式。python的多进程容易吧,同样的功能,比java、c++容易多咯
import multiprocessing
import time
class Producer(multiprocessing.Process):
def __init__(self, q):
multiprocessing.Process.__init__(self) #必须先实例化父类
self._q = q
def run(self):
while True:
self._q.put('time is %s' % time.time()) #往生产者队列中放时间
time.sleep(1)
class Consumer(multiprocessing.Process):
def __init__(self, q, n): #q:队列,n:消费者进程编号
multiprocessing.Process.__init__(self)
self._q = q
self._n = n
def run(self):
while True:
msg = None
try:
msg = self._q.get() #从队列中取东西容易抛错
except :
time.sleep(1)
continue
if msg:
print 'in consumer %s %s' % (self._n, msg)
if __name__ == "__main__":
q = multiprocessing.Queue() #获取一个队列
producer = Producer(q) #实例一个生产者
c1 = Consumer(q, 1) #获取一个消费者实例
c2 = Consumer(q, 2) #获取一个消费者实例
producer.start() #将生产者启动
c1.start() #将消费者启动
c2.start() #将消费者启动