【python】多进程、多线程、序列
一、多进程
1.子进程永远返回0
,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()
就可以拿到父进程的ID。
2.multiprocessing
multiprocessing
模块提供了一个Process
类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束
import os,time,random
from multiprocessing import Process
#运行多个子进程
def run_child_process(name):
print("run child process %s(%s)"%(name,os.getpid())) if __name__=='__main__':
print("parent process %s"%os.getpid())
p1=Process(target=run_child_process,args=("p1",))
p1.start()
p1.join()
print("child process end")
3.进程池 pool
如果要启动大量的子进程,可以用进程池的方式批量创建子进程:
from multiprocessing import Pool
import os,time,random
def long_time_task(name):
print("run task %s(%s)"%(name,os.getpid()))
start=time.time()
time.sleep(random.random()*3)
end=time.time()
print("task %s takes %0.2f seconds"%(name,(end-start))) if __name__=='__main__':
print("parent process %s"%os.getpid())
p=Pool(4)
#pool的默认值是cpu数
for i in range(5):
p.apply_async(long_time_task,args=(i,))
print("waiting for all subprocess done")
p.close()
p.join()
print("all subprocess done")
执行结果:
Parent process 4984.
Waiting for all subprocesses done...
Run task 3 (9496)...
Task 3 runs 1.65 seconds.
Run task 4 (9496)...
Task 4 runs 0.16 seconds.
Run task 0 (11036)...
Task 0 runs 2.25 seconds.
Run task 2 (8680)...
Task 2 runs 2.67 seconds.
Run task 1 (11100)...
Task 1 runs 2.97 seconds.
All subprocesses done.
[Finished in 3.7s]
二、多线程
多任务可以由多进程完成,也可以由一个进程内的多线程完成。
我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程
1.启动线程
import threading,time
def loop():
print("thread %s is running..."%threading.current_thread().name)
n=0
while n<5:
n=n+1
print("thread %s>>>%s"%(threading.current_thread().name,n))
time.sleep(1)
print("thread %s is 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 is ended"%threading.current_thread().name)
执行结果:
thread MainThread is running
thread loopthread is running...
thread loopthread>>>1
thread loopthread>>>2
thread loopthread>>>3
thread loopthread>>>4
thread loopthread>>>5
thread loopthread is ended
thread MainThread is ended
[Finished in 5.3s]
2.lock
多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了
import time,threading
balance=0
lock=threading.Lock()
def change_it(n):
global balance
balance=balance+n
balance=balance-n def run_thread(n):
for i in range(100000):
lock.acquire()
try:
change_it(n)
finally:
lock.release()
t1=threading.Thread(target=run_thread,args=(5,))
t2=threading.Thread(target=run_thread,args=(8,))
t1.start()
t2.start()
t1.join()
t1.join()
print(balance)
三、队列
1.Process
之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing
模块包装了底层的机制,提供了Queue
、Pipes
等多种方式来交换数据。
我们以Queue
为例,在父进程中创建两个子进程,一个往Queue
里写数据,一个从Queue
里读数据:
from multiprocessing import Process, Queue
import os, time, random
# 写数据进程执行的代码:
def write(q):
print('Process to write: %s' % os.getpid())
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random()) # 读数据进程执行的代码:
def read(q):
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value) if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()
# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr.terminate()
原文地址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431927781401bb47ccf187b24c3b955157bb12c5882d000
https://yuedu.baidu.com/ebook/0f6a093b7dd184254b35eefdc8d376eeaeaa17e3?pn=1&rf=https%3A%2F%2Fyuedu.baidu.com%2Febook%2F0f6a093b7dd184254b35eefdc8d376eeaeaa17e3
最新文章
- KnockoutJS 3.X API 第六章 组件(4) 自定义元素
- AO安装需要Microsoft Visual Studio 2013?
- php 文件上传
- Python实现打印二叉树某一层的所有节点
- [CareerCup] 9.1 Climbing Staircase 爬楼梯
- LeetCode Inorder Successor in BST
- [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题
- 使用apache common-io 监控文件变化--转
- phpExcel使用与中文处理教程
- find . / -newer oldest_file.txt ! -newer newest_file.txt
- nginx小问题
- Extjs6随笔(终篇)——内容总结
- (二)—Linux远程连接与常用命令
- 阿里云大数据计算服务 - MaxCompute (原名 ODPS)
- mybatis学习系列三(部分)
- JavaScript中var和this定义变量的区别
- 安全测试6_Web安全工具第一节(浏览器入门及扩展)
- VS2015+OpenGL4.0开发编译时弹出错误:glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符号在函数 _GetRegistrySysColors@8 中被引用
- 5月14日 绿城育华NOIP巨石杯试卷解析
- Thinkphp5笔记二:创建模块