manager数据共享
- 通过Manager可实现进程间数据的共享。Manager()返回的manager对象会通过一个服务进程,来使其他进程通过代理的方式操作python对象。manager对象支持 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value ,Array.
from multiprocessing import Manager, Process
def worker(dt, lt):
for i in range(10):
dt[i] = i*i
lt += [x for x in range(11, 16)]
if __name__ == '__main__':
manager = Manager()
dt = manager.dict()
lt = manager.list()
p = Process(target=worker, args=(dt, lt))
p.start()
p.join(timeout=3)
print(dt)
print(lt)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
[11, 12, 13, 14, 15]
pool进程池
- 一般我们是通过动态创建子进程(或子线程)来实现并发服务器的,但是会存在这样一些缺点:
1、动态创建进程(或线程)比较耗费时间,这将导致较慢的服务器响应。
2、动态创建的子进程通常只用来为一个客户服务,这样导致了系统上产生大量的细微进程(或线程)。进程和线程间的切换将消耗大量CPU时间。
3、动态创建的子进程是当前进程的完整映像,当前进程必须谨慎的管理其分配的文件描述符和堆内存等系统资源,否则子进程可能复制这些资源,从而使系统的可用资源急剧下降,进而影响服务器的性能。 所以呢,就引入了进程池与线程池的概念。
import time
import multiprocessing
def fun(msg):
print("#########start#### {0}".format(msg))
time.sleep(3)
print("#########end###### {0}".format(msg))
if __name__ == '__main__':
print("start main")
pool = multiprocessing.Pool(processes=3)
for i in range(1, 7):
msg = "hello {0}".format(i)
pool.apply_async(fun, (msg,))
pool.close()
pool.join()
print("end main")
start main
startend hello 2
startend hello 4
end hello 6
end main
多线程
- 1、多线程的理解
多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和加锁比较麻烦。
'''
多线程 密集型io
多线程的实现有两种方法:
方法1:
和多进程类似
方法2:
通过继承的方式
'''
import threading
def worker(args):
print("开始子进程 {0}".format(args))
print("结束子进程 {0}".format(args))
if __name__ == '__main__':
print("start main")
t1 = threading.Thread(target=worker, args=(1,))
t2 = threading.Thread(target=worker, args=(2,))
t1.start()
t2.start()
print("end main")
start main
开始子进程 1
结束子进程 1
开始子进程 2
end main
结束子进程 2
import threading
import time
class Hello(threading.Thread):
def __init__(self, args):
super(Hello, self).__init__()
self.args = args
def run(self):
print("开始子进程 {0}".format(self.args))
time.sleep(1)
print("结束子进程 {0}".format(self.args))
if __name__ == '__main__':
a = 1
print("start main")
t1 = Hello(1)
t2 = Hello(2)
t1.start()
t2.start()
print("end main")
start main
开始子进程 1
开始子进程 2
end main
结束子进程 2
结束子进程 1
类的方式实现
import threading
import time
class Hello(threading.Thread):
def __init__(self, args):
super(Hello, self).__init__()
self.args = args
global a
print("a = {0}".format(a))
a += 1
def run(self):
print("开始子进程 {0}".format(self.args))
print("结束子进程 {0}".format(self.args))
if __name__ == '__main__':
a = 1
print("start main")
t1 = Hello(5)
time.sleep(3)
t2 = Hello(5)
t1.start()
t2.start()
print("#####a = {0}####".format(a))
print("end main")
start main
a = 1
a = 2
开始子进程 5
结束子进程 5
end main
开始子进程 5
结束子进程 5
线程锁
- 由于存在多个进程共同去修改某个数据的问题,所以必须要用到lock()
import threadpool
def hello(m, n, o):
print("m = {0} n={1} o={2}".format(m, n, o))
if __name__ == '__main__':
lst_vars_1 = ['1', '2', '3']
lst_vars_2 = ['4', '5', '6']
func_var = [(lst_vars_1, None), (lst_vars_2, None)]
pool = threadpool.ThreadPool(2)
requests = threadpool.makeRequests(hello, func_var)
[pool.putRequest(req) for req in requests]
pool.wait()
m = 1 n=2 o=3
m = 4 n=5 o=6
[Finished in 2.3s]