一、多进程

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模块包装了底层的机制,提供了QueuePipes等多种方式来交换数据。

我们以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

最新文章

  1. KnockoutJS 3.X API 第六章 组件(4) 自定义元素
  2. AO安装需要Microsoft Visual Studio 2013?
  3. php 文件上传
  4. Python实现打印二叉树某一层的所有节点
  5. [CareerCup] 9.1 Climbing Staircase 爬楼梯
  6. LeetCode Inorder Successor in BST
  7. [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题
  8. 使用apache common-io 监控文件变化--转
  9. phpExcel使用与中文处理教程
  10. find . / -newer oldest_file.txt ! -newer newest_file.txt
  11. nginx小问题
  12. Extjs6随笔(终篇)——内容总结
  13. (二)—Linux远程连接与常用命令
  14. 阿里云大数据计算服务 - MaxCompute (原名 ODPS)
  15. mybatis学习系列三(部分)
  16. JavaScript中var和this定义变量的区别
  17. 安全测试6_Web安全工具第一节(浏览器入门及扩展)
  18. VS2015+OpenGL4.0开发编译时弹出错误:glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符号在函数 _GetRegistrySysColors@8 中被引用
  19. 5月14日 绿城育华NOIP巨石杯试卷解析
  20. Thinkphp5笔记二:创建模块

热门文章

  1. jQuery.fn.extend与jQuery.extend的区别
  2. linux如何添加服务为系统服务快速启动或关闭
  3. django 之(二) --- 源码分析
  4. Mysql 设置远程连接(自用-----仅供参考)
  5. Mysql 索引失效场景
  6. Mybatis之自动生成
  7. nginx http跳https配置
  8. Linux上面mount 域控的目录 超时 然后提示 error的解决办法
  9. Python中几个必须知道的函数
  10. 作为小白该如何抉择python编辑器?