python进程和线程


进程是执行程序过程中产生一系列内容,是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位,每个进程中至少包括一个主线程,一个线程只能属于一个进程,而一个进程可以有多个线程,进程之间不能直接共享资源


python中常用的线程模块有_threadthreading
打印激活的线程个数及线程信息

import threading
import time


def job():
    print("这是一个需要执行的任务")
    # 激活的线程个数
    print("当前线程的个数:", threading.active_count())
    # 打印当前线程的详细信息
    print("当前线程信息:", threading.current_thread())
    time.sleep(100)


job()

在这里插入图片描述

  • _thread模块创建多线程
import _thread
import threading
import time


def job(name):
    print("这是一个需要执行的任务")
    # 激活的线程个数
    print("当前线程的个数:", threading.active_count())
    # 打印当前线程的详细信息
    print("当前线程信息:", threading.current_thread())
    print(name, time.ctime())
    time.sleep(2)


if __name__ == "__main__":
    # 创建多个线程, 但是没有开始执行任务;
    _thread.start_new_thread(job, ('thread1',))
    _thread.start_new_thread(job, ('thread2',))
    while True:
        pass

python进程和线程_第1张图片

  • threading模块中通过实例化对象创建多线程
import threading
import time


def job(name):
    print("这是一个需要执行的任务: %s" % (name))
    # 激活的线程个数
    print("当前线程的个数:", threading.active_count())
    # 打印当前线程的详细信息
    print("当前线程信息:", threading.current_thread())
    time.sleep(1)

    print(name, time.ctime())


if __name__ == "__main__":
    # 创建多个线程
    t1 = threading.Thread(target=job, name='job1', args=("job1-name",))
    t1.start()
    t2 = threading.Thread(target=job, name='job2', args=("job2-name",))
    t2.start()
    t1.join()
    t2.join()
    print('hello')

python进程和线程_第2张图片
可以看到实现了多线程,线程个数统计包括主线程,t1.start()表示启动线程,t1.join()表示阻塞主线程,等待子进程 t1 执行结束后,执行主线程的内容

  • set_daemon设置守护进程,当主线程执行结束,让没有执行的线程强制结束
import threading
import time


# 任务1:
def music(name):
    for i in range(2):
        print("正在听音乐%s" % (name))
        time.sleep(1)
        print('完成')


# 任务2:
def code(name):
    for i in range(2):
        print("正在编写代码%s" % (name))
        time.sleep(2)
        print('完成')


if __name__ == '__main__':
    start_time = time.time()
    # music("中国梦")
    # code("爬虫")

    t1 = threading.Thread(target=music, args=("中国梦",))
    t2 = threading.Thread(target=code, args=("爬虫",))
    # 将t1线程生命为守护线程, 如果设置为True, 子线程启动, 当主线程执行结束, 子线程也结束
    # 设置setDaemon必须在启动线程之前进行设置;
    t1.setDaemon(True)
    t2.setDaemon(True)
    t1.start()
    t2.start()
    # 等待所有的子线程执行结束之后, 继续执行主线程的内容;
    # t1.join()
    # t2.join()
    print("花费时间: %s" % (time.time() - start_time))

python进程和线程_第3张图片

  • 通过继承创建线程
import threading


# 类的继承
class IpThread(threading.Thread):
    # 重写构造方法;
    def __init__(self, jobname):
        super(IpThread, self).__init__()
        self.jobname = jobname

    # 将多线程需要执行的任务重写到run方法中;
    def run(self):
        print("this is  a job")


t1 = IpThread(jobname="new job")
t1.start()

在这里插入图片描述

  • 带参数的继承
import json
import threading
from urllib.error import HTTPError
from urllib.request import urlopen
import time


class IpThread(threading.Thread):
    # 重写构造方法;如果执行的任务需要传递参数, 那将参数通过构造函数与self绑定;
    def __init__(self, jobname, ip):
        super(IpThread, self).__init__()
        self.jobname = jobname
        self.ip = ip

        # 将多线程需要执行的任务重写到run方法中;

    def run(self):
        try:
            # 需要有一个参数, 传ip;
            url = "http://ip.taobao.com/service/getIpInfo.php?ip=%s" % (self.ip)
            # 根据url获取网页的内容, 并且解码为utf-8格式, 识别中文;
            text = urlopen(url).read().decode('utf-8')
        except HTTPError as e:
            print("Error: %s获取地理位置网络错误" % (self.ip))
        else:
            # 将获取的字符串类型转换为字典, 方便处理
            d = json.loads(text)['data']
            country = d['country']
            city = d['city']
            print("%s:" % (self.ip), country, city)


def use_thread():
    start_time = time.time()
    ips = ['172.25.254.250', '8.8.8.8',
           '172.25.254.250', '8.8.8.8',
           '172.25.254.250', '8.8.8.8']
    threads = []
    for ip in ips:
        t = IpThread(jobname="爬虫", ip=ip)
        threads.append(t)
        t.start()
    # 等待所有的子线程执行结束
    [thread.join() for thread in threads]
    print("Success, 运行时间为%s" % (time.time() - start_time))


if __name__ == "__main__":
    use_thread()

python进程和线程_第4张图片
通过遍历参数列表,创建多线程并启动,在遍历完成后设置阻塞主线程,等待子进程全部完成后继续执行主线程

  • 线程同步线程锁
    当多个线程对同一个数据进行修改时,可能会出现不可预料的情况
    添加方式
import threading


def add(lock):
    # 2. 操作变量之前进行加锁
    lock.acquire()
    global money
    for i in range(1000000):
        money += 1
    # 3. 操作变量完成后进行解锁
    lock.release()


def reduce(lock):
    # 2. 操作变量之前进行加锁
    lock.acquire()
    global money
    for i in range(1000000):
        money -= 1
    # 3. 操作变量完成后进行解锁
    lock.release()


if __name__ == '__main__':
    money = 0
    # 1. 实例化一个锁对象
    lock = threading.Lock()
    t1 = threading.Thread(target=add, args=(lock,))
    t2 = threading.Thread(target=reduce, args=(lock,))
    t1.start()
    t2.start()
    # 等待所有子线程执行结束
    t1.join()
    t2.join()
    print("最终金额为:%s" % (money))
  • GIL全局解释器锁
    python的解释器默认每次只允许一个线程执行,在执行过程中,会先设置GIL,切换到线程去运行对应的任务,在运行阶段若是执行完成,或者 time.sleep() ,再或者需要其他信息才能继续执行时,会把当前线程设置为睡眠状态,然后解锁GIL,并重复执行

Python并不支持真正意义上的多线程。Python中提供了多线程包,但是如果你想通过多线程提高代码的速度,使用多线程包并不是个好主意。Python中有一个被称为Global Interpreter Lock(GIL)的东西,它会确保任何时候你的多个线程中,只有一个被执行。线程的执行速度非常之快,会让你误以为线程是并行执行的,但是实际上都是轮流执行。经过GIL这一道关卡处理,会增加执行的开销。这意味着,如果你想提高代码的运行速度,使用threading包并不是一个很好的方法。


对于I/O密集型操作,适合使用多线程操作,对于CPU/计算密集型操作,则不适合使用多线程操作

  • 队列与多线程
    在多线程执行任务中,会产生一些数据,为其他程序执行作铺垫;在多线程中是不能返回任务执行结果的,因此需要一个容器来存储多线程产生的数据
import threading
from collections import Iterable
from queue import Queue


def job(l, queue):
    # 将任务的结果存储到队列中;
    queue.put(sum(l))


def use_thread():
    # 实例化一个队列, 用来存储每个线程执行的结果;
    q = Queue()
    # # 入队
    # q.put(1)
    li = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7, 8], [2, 3, 4, 5, 6]]
    threads = []
    for i in li:
        t = threading.Thread(target=job, args=(i, q))
        threads.append(t)
        t.start()
    # join方法等待所有子线程之心结束
    [thread.join() for thread in threads]
    # 从队列里面拿出所有的运行结果
    result = [q.get() for _ in li]
    print(result)
    print(isinstance(q, Iterable))


if __name__ == "__main__":
    use_thread()

在这里插入图片描述

  • ThreadPool线程池
from concurrent.futures import ThreadPoolExecutor
import time


# 需要执行的任务
def job():
    print("this is a job")
    return "hello"


if __name__ == '__main__':
    # 实例化对象, 线程池包含10个线程来处理任务;
    pool = ThreadPoolExecutor(max_workers=10)
    # 往线程池里面扔需要执行的任务, 返回一个对象,( _base.Future实例化出来的)
    f1 = pool.submit(job)
    f2 = pool.submit(job)
    # 判断任务是否执行结束
    print(f1.done())
    time.sleep(1)
    print(f2.done())
    # 获取任务执行的结果
    print(f1.result())
    print(f2.result())

python进程和线程_第5张图片
在线程池中,submit 提交任务

  • 线程池与map的关系
    方法一:
from urllib.error import HTTPError
from urllib.request import urlopen
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
import time

URLS = ['http://httpbin.org', 'http://example.com/',
        'https://api.github.com/'] * 10


def get_page(url, timeout=3):
    try:
        content = urlopen(url).read()
        return {'url': url, 'len': len(content)}
    except HTTPError as e:
        return {'url': url, 'len': 0}


# 方法1: submit提交任务
start_time = time.time()
pool = ThreadPoolExecutor(max_workers=20)
futuresObj = [pool.submit(get_page, url) for url in URLS]
# 注意: 传递的时包含futures对象的序列, as_complete, 返回已经执行完任务的future对象,
# 直到所有的future对应的任务执行完成, 循环结束;
for finish_fs in as_completed(futuresObj):
    print(finish_fs.result() )
for future in futuresObj:
    print(future.result())
print("执行时间:%s" % (time.time() - start_time))
#####
{'url': 'http://example.com/', 'len': 1270}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
执行时间:3.0462844371795654

方法二:

from urllib.error import HTTPError
from urllib.request import urlopen
from concurrent.futures import ThreadPoolExecutor

URLS = ['http://httpbin.org', 'http://example.com/',
        'https://api.github.com/'] * 10


def get_page(url, timeout=3):
    try:
        content = urlopen(url).read()
        return {'url': url, 'len': len(content)}
    except HTTPError as e:
        return {'url': url, 'len': 0}


# 方法2:通过map方式执行
pool = ThreadPoolExecutor(max_workers=20)
for res in pool.map(get_page, URLS):
    print(res)
#####
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
{'url': 'http://httpbin.org', 'len': 10122}
{'url': 'http://example.com/', 'len': 1270}
{'url': 'https://api.github.com/', 'len': 2039}
  • LINUX创建子进程
import os
import time

print("当前进程(pid=%d)正在运行..." % (os.getpid()))
print("当前进程的父进程(pid=%d)正在运行..." % (os.getppid()))
print("正在创建子进程......")
pid = os.fork()
pid2 = os.fork()
print("第1个:", pid)
print("第2个: ", pid2)

if pid == 0:
    print("这是创建的子进程, 子进程的id为%s, 父进程的id为%s"
          % (os.getpid(), os.getppid()))
else:
    print("当前是父进程[%s]的返回值%s" % (os.getpid(), pid))
time.sleep(100)
#####
当前进程(pid=5714)正在运行...
当前进程的父进程(pid=5378)正在运行...
正在创建子进程......
第1个: 5715
第2个:  5716
当前是父进程[5714]的返回值5715
第1个: 5715
第2个:  0
当前是父进程[5716]的返回值5715
第1个: 0
第2个:  5717
这是创建的子进程, 子进程的id为5715, 父进程的id为5714
第1个: 0
第2个:  0
这是创建的子进程, 子进程的id为5717, 父进程的id为5715

Linux创建子进程的原理:先有父进程,再有子进程,通过 fork() 函数实现,如果父进程结束, 子进程也随之结束,其中fork函数的返回值:调用该方法一次, 返回两次,子进程返回一个0,父进程返回子进程的pid,os.getpid()获取当前进程的pid,os.getppid()获取当前进程的父进程的id

  • 通过实例化对象创建多进程
    在面对I/O密集型任务时,使用多线程,在处理密集型任务时,则使用多进程,充分利用CPU,将任务提交给多个CPU去执行。
import multiprocessing


def job():
    print("当前子进程的名称为%s" % (multiprocessing.current_process()))


# 创建一个进程对象
p1 = multiprocessing.Process(target=job)
# 运行多进程, 执行任务
p1.start()
# 创建一个进程对象
p2 = multiprocessing.Process(target=job)
# 运行多进程, 执行任务
p2.start()
# 等待所有的子进程执行结束, 再执行主进程的内容
p1.join()
p2.join()
print("任务执行结束.......")
#####
当前子进程的名称为
当前子进程的名称为
任务执行结束.......
  • 通过继承实现多进程
import multiprocessing


class JobProcess(multiprocessing.Process):
    # 重写Process的构造方法, 获取新的属性
    def __init__(self, queue):
        super(JobProcess, self).__init__()
        self.queue = queue

    # 重写run方法, 将执行的任务放在里面即可
    def run(self):
        print("当前子进程的名称为%s" % (multiprocessing.current_process()))


processes = []
# 启动10个子进程, 来处理需要执行的任务;
for i in range(10):
    # 实例化对象;
    p = JobProcess(queue=3)
    processes.append(p)
    # 启动多进程, 处理需要执行的任务;
    p.start()
# 等待所有的子进程执行结束, 再继续执行主进程
[process.join() for process in processes]
# 执行主进程
print("任务执行结束.......")
#####
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
当前子进程的名称为
任务执行结束.......

对于多进程,开启的进程数有瓶颈,取决于CPU的个数。如果处理的数据比较小, 不建议使用多进程, 因为进程的创建和销毁需要时间,开启的进程数越多,不一定效率越高。如果处理的数据量足够大, 0<开启的进程数

  • 守护进程
import multiprocessing
import time


def job():
    name = multiprocessing.current_process()
    print("开始运行")
    time.sleep(3)
    print("结束进程")


if __name__ == '__main__':
    # 启动一个子进程
    p1 = multiprocessing.Process(target=job, name='use deamon')
    # True/False
    p1.daemon = True
    p1.start()
    # join等待所有子进程执行结束, 再执行主进程
    # p1.join()
    # 主进程执行
    print("程序执行结束")

在这里插入图片描述
守护进程,主进程执行结束, 子进程不再继续执行

  • 终止进程
import time
import multiprocessing


def job():
    print("start.....")
    time.sleep(10)
    print('end.......')


if __name__ == '__main__':
    p = multiprocessing.Process(target=job)
    print("Before:", p.is_alive())
    p.start()  # 启动子进程
    print("During:", p.is_alive())
    p.terminate()  # 终止子进程
    print('terminate:', p.is_alive())
    # p.join()  # 等待子进程彻底终止
    time.sleep(1)
    print("joined:", p.is_alive())
#####
Before: False
During: True
terminate: True
joined: False

在执行terminate()后,进程被终止

  • 生产者消费者
import multiprocessing
from multiprocessing import Queue
import time


class Producer(multiprocessing.Process):
    # 往队列里面写内容
    def __init__(self, queue):
        super(Producer, self).__init__()
        self.queue = queue

    def run(self):
        for i in range(10):
            self.queue.put(i)
            time.sleep(0.1)
            print("传递消息, 内容为:%s" % (i))


class Consumer(multiprocessing.Process):
    # 读取队列里面的内容
    def __init__(self, queue):
        super(Consumer, self).__init__()
        self.queue = queue

    def run(self):
        # 判断队列是否为空, 如果是, 跳出循环, 不会再去从队列获取数据;
        # while not self.queue.empty():
        while True:
            time.sleep(0.1)
            print("读取进程传递的消息:%s" % (self.queue.get()))


if __name__ == "__main__":
    q = Queue()
    p1 = Producer(q)
    c1 = Consumer(q)
    p1.start()
    c1.start()
    p1.join()
    c1.terminate()
    c1.join()
    print('all done')
#
读取进程传递的消息:0
传递消息, 内容为:0
读取进程传递的消息:1
传递消息, 内容为:1
读取进程传递的消息:2
传递消息, 内容为:2
读取进程传递的消息:3
传递消息, 内容为:3
读取进程传递的消息:4
传递消息, 内容为:4
读取进程传递的消息:5
传递消息, 内容为:5
读取进程传递的消息:6
传递消息, 内容为:6
读取进程传递的消息:7
传递消息, 内容为:7
读取进程传递的消息:8
传递消息, 内容为:8
读取进程传递的消息:9
传递消息, 内容为:9
all done
  • 分布式进程
    当任务需要处理的数据非常大,希望多台主机共同处理任务
    实现方式:
    multiprocessing.managers子模块里面可以实现将进程分布到多台机器
    BaseManager: 提供了不同机器进程之间共享数据的一种方法(ip:port)
    Master: 管理端, 分配任务给其他主机;
    Worker1: 被管理端, 处理master给予的任务;
    Worker2:被管理端, 处理master给予的任务;
    管理端:
import random
from queue import Queue
from multiprocessing.managers import  BaseManager
# 1. 创建需要的队列
# task_queue存储的是任务需要传递的参数
task_queue = Queue()
# result_queue存储的是任务执行结果
result_queue = Queue()
# 2. 将队列注册到网络上
# 需要将两个队列注册到网络上, 使得其他主机可以访问;
BaseManager.register('get_task_queue',  callable=lambda : task_queue)
BaseManager.register('get_result_queue',  callable=lambda : result_queue)
# 绑定端口为为4000, 暗号/密钥为hello;
manager = BaseManager(address=('192.168.1.137', 4000), authkey=b'hello')
# 3. 启动manager, 开始共享队列;
manager.start()
# 4. 通过网络访问共享的Queue对象,
# manager.register: 注册一个队列, 唯一标识'get_task_queue'
# manager.get_task_queue()调用注册, 调用过程中执行的内容为callable只想的函数;
task = manager.get_task_queue()
result =  manager.get_result_queue()
# 5. 开始往队列里面放执行任务需要的数据;
for i in range(100):
    n = random.randint(1,1000)
    task.put(n)
    print("任务列表加入任务: %d" %(n))
# 6. 从result队列里面读取各个及机器执行的结果;
for j in range(100):
    res = result.get()
    print("队列任务的执行结果:%s" %(res))
# 7. 关闭manager, 取消共享队列;
manager.shutdown()

被管理端:

from multiprocessing.managers import BaseManager
# 1. 连接Master端, 获取共享的队列;
# address写的是master端的ip和共享的端口, authkey与master端保持一致;
import time
worker = BaseManager(address=('192.168.1.137', 4000), authkey=b'hello')
# 2. 注册队列, 获取共享端的队列内容
BaseManager.register('get_task_queue')
BaseManager.register('get_result_queue')
# 3. 去连接
worker.connect()
# 4. 通过网络访问共享的Queue对象,
# manager.register: 注册一个队列, 唯一标识'get_task_queue'
# manager.get_task_queue()调用注册, 调用过程中执行的内容为callable只想的函数;
task = worker.get_task_queue()
result =  worker.get_result_queue()
# 5. 读取管理端共享的任务, 依次执行;
for i in range(50):
    n = task.get()
    print("运行任务 %d ** 2:" %(n))
    res = "%d ** 2 = %d" %(n, n**2)
    time.sleep(1)
    # 将运行结果放入reesult队列
    result.put(res)
print("执行结束.....")

管理端:
python进程和线程_第6张图片
被管理端:
python进程和线程_第7张图片

  • 进程池
import multiprocessing


def job(id):
    print('start %d.....' % (id))
    print('end %d.....' % (id))


# 创建一个进程池对象
pool = multiprocessing.Pool(10)
# 给进程池的进程分配任务
for i in range(10):
    pool.apply_async(job, args=(i,))
pool.close()
# 等待所有的子进程执行结束
pool.join()
print('success')
#
start 0.....
end 0.....
start 1.....
end 1.....
start 3.....
start 2.....
end 3.....
end 2.....
start 5.....
end 5.....
start 4.....
end 4.....
start 6.....
end 6.....
start 7.....
end 7.....
start 8.....
end 8.....
start 9.....
end 9.....
success
  • 进程池—ProcessPoolExecutor
    submit方法
from concurrent.futures import ProcessPoolExecutor


def job(id):
    print('start %d.....' % (id))
    print('end %d.....' % (id))
    return id


# submit
pool = ProcessPoolExecutor(max_workers=4)
# 分配任务给子进程, 并且返回一个Future对象;
f1 = pool.submit(job, 1)
# 获取进程是否执行结束;
f1.done()
# 获取子进程执行的结果
f1.result()
#
start 1.....
end 1.....

map方法

from concurrent.futures import ProcessPoolExecutor


def job(id):
    print('start %d.....' % (id))
    print('end %d.....' % (id))
    return id


pool = ProcessPoolExecutor(max_workers=4)
for res in pool.map(job, range(1, 100)):
    print(res)

python进程和线程_第8张图片

你可能感兴趣的:(python进程和线程)