廖雪峰python学习笔记【16】进程和线程:多进程、多线程

一、多进程

1. fork返回两次的原因:调用fork时,操作系统把当前进程复制了一份,然后fork在父子进程分别返回了一次。

2. python的os模块内的fork只能在linux类系统上调用:

    2.1 import os

    2.2 pid = os.fork() # pid在子进程中为0;在父进程中为子进程的进程id。

3. multiprocessing模块

    3.1 multiprocessing是跨平台版本的多进程模块。

    3.2 创建子进程示例:

        
from multiprocessing import Process # 从multiprocessing模块导入Process类。
pid = Process(target = childFunc, args = ('test', )) # 创建一个Process实例,即表示创建了一个子进程。target成员为子进程的执行函数;args成员为参数。
pid.start() # 用于启动子进程。
pid.join() # 等待子进程结束。通常用于进程间的同步。

    3.3 通过进程池创建子进程示例:

from multiprocessing import Pool # 从multiprocessing模块导入Pool类。
pids = Pool(4) # 创建最多拥有四个进程的进程池
for loop in range(4);
    pids.apply_async(childFunc, args = (loop, ))
    pids.close() # 调用join()前必须先调用close()。
    pids.join() # 等待所有子进程执行结束。

4. subprocess模块

    4.1 类似于linux上的system()系统调用。

5. 进程间通信

    5.1 multiprocessing模块提供了Queue和Pipes等多种方式支持进程间通信。

    5.2 通过Queue的put()方法向队列中写数据;通过get()方法读出队列中的数据。

二、多线程。

1. python标准库提供两个线程模块:_thread和threading。_thread是低级模块;threading是高级模块,封装自_thread模块;一般使用threading模块。

2. 启动一个线程就是创建一个Thread类的实例,并调用实例的start()方法开始执行。示例:

    
import threading
td = threading.Thread(target = threadFunc, name = 'testThread', args = (4, ))
td.start()

3. threading模块的current_thread()方法用来返回当前线程的实例。threading.current_thread().name是当前线程的名字。

4. Lock

    4.1 注意:高级语言的一条语句在CPU执行时是若干条语句。

    4.2 全局变量在多线程间是共享的,修改变量前需要加锁。示例:

        
lock = threading.Lock() # 创建Lock类的实例
lock.acquire() # 获取锁
try:
    do something
finally:
    lock.release()

5. 多核CPU:

    5.1 GIL锁:Global Interpreter Lock全局解释器锁。

    5.2 每个进程拥有一个GIL锁。

    5.3 官方CPython解释器在执行python线程前需要首先获得GIL锁,执行100条字节码后释放GIL锁,其他线程获取锁后依次执行。因此python线程不能真正利用多核。

    5.4 python真正利用多核只能使用进程。


猜你喜欢

转载自blog.csdn.net/liufuchun111/article/details/80666941