Python__模块(TIME-进程/线程)__concurrent / multiprocessing

concurrent(简介)

进程或线程的使用。


concurrent(了解)

【线程进程区别】

  • 线程是共享内存空间。

  • 进程是内存独立状态。

同一个进程的线程之间可以直接交流。

两个进程想通信,必须通过一个中间代理来实现。

使用多线程能充分利用 CPU 来提供程序的执行效率。

每一个进程启动时都会最先产生一个线程,即主线程,然后主线程会再创建其他的子线程。

一个进程可包含多个线程。

【同步异步】

同步

提交了一个任务,必须等任务执行完了(拿到返回值),才能执行下一行代码。

相当于执行任务的串行执行。

异步

交了一个任务,无需等执行完,可以直接执行下一行代码。


concurrent(参数列表)

concurrent.futures

模块提供了高度封装的异步调用接口。

ThreadPoolExecutor

线程池,提供异步调用

ProcessPoolExecutor

进程池,提供异步调用

subprocess

子进程操作

result(timeout=None)

取得结果

add_done_callback(fn)

回调函数

submit(fn, *args, **kwargs)

异步提交任务

wait=True

等待池内所有任务执行完毕回收完资源后才继续

wait=False

立即返回,并不会等待池内的任务执行完毕,

但不管wait参数为何值,整个程序都会等到所有任务执行完毕

shutdown(wait=True)

相当于进程池的pool.close()+pool.join()操作

map(func, *iterables, timeout=None, chunksize=1)

取代for循环submit的操作。


concurrent(参考代码)

简单的多线程操作

from concurrent.futures import ThreadPoolExecutor
import time

def task(i):
    print(f"在执行任务{i}")
    print("假设这是一个URL请求的地址....")
    time.sleep(5)

pool = ThreadPoolExecutor(2)  # 4个线程
for i in range(20):
    pool.submit(task, i)

上一个例子的简化版(map)


# 例子-map用法
from concurrent.futures import ThreadPoolExecutor
from threading import Thread, currentThread
import time

def task(i):
    print(f"{currentThread().name} 在执行任务{i}")
    time.sleep(1)

if __name__ == "__main__":
    pool = ThreadPoolExecutor(4)
    pool.map(task, range(0, 20))  # map取代了for+submit

multiprocessing(简介)

进程的进阶用法。


multiprocessing(了解)

multiprocessing-模块用来开启子进程。

功能:支持子进程,通信和共享数据,执行不同执行的同步。

提供->Process,Queue,Pipe,Lock等组件。


multiprocessing(参数列表)

Process类

由该类实例化得到的对象,可用来开启一个子进程。

【语法】 Process([group [, target [, name [, args [, kwargs]]]]])

group  (暂时忽略) 参数未使用,值始终为None。

target (函数) 表示调用对象,即子进程要执行的任务。

args   (函数的参数) 表示调用对象的位置参数元组,args=(1,2,'mike')。

kwargs (暂时忽略) 表示调用对象的字典,kwargs={'name':'mike','age':'18'}。

常用函数

start()

(启动进程)调用该子进程中的run()

run()

(进程启动时运行的方法)正是它去调用target指定的函数。

terminate()

(强制终止进程),不会进行任何清理操作,如果创建了子进程,

该子进程就成了僵尸进程,使用该方法需要特别小心这种情况,

如果还保存了一个锁那么也将不会被释放,进而导致死锁。

is_alive()

进程仍然运行,返回True。

join([timeout])

主进程等待终止(主进程处于等的状态)

daemon

默认值为False,如果设为True,代表子进程为后台运行的守护进程,

父进程终止时,子进程也随之终止,并且设定为True后。

name

进程的名称

pid

进程的pid


multiprocessing(参考代码)

单进程

import multiprocessing
import time

def func(msg):
    for i in range(20):
        print(msg, i)
        time.sleep(1)

if __name__ == "__main__":
    p = multiprocessing.Process(target=func, args=("input content....",))
    p.start()
    p.join()

    print("Sub-process done.")

多进程

import multiprocessing
import time

def fc1(msg):
    for i in range(3):
        print("{}:黄岛主 正在进行任务{}....".format(msg, i + 1))
        time.sleep(1)
    print(">>>>>> {}大佬 任务完成".format(msg))


def fc2(msg):
    for i in range(2):
        print("{}:欧阳锋 正在进行任务{}....".format(msg, i + 1))
        time.sleep(1)
    print(">>>>>> {}大佬 任务完成".format(msg))


def fc3(msg):
    for i in range(5):
        print("{}:段大师 正在进行任务{}....".format(msg, i + 1))
        time.sleep(1)
    print(">>>>>> {}大佬 任务完成".format(msg))


def fc4(msg):
    for i in range(2):
        print("{}:洪七公 正在进行任务{}....".format(msg, i + 1))
        time.sleep(1)
    print(">>>>>> {}大佬 任务完成".format(msg))


if __name__ == "__main__":
    pool = multiprocessing.Pool(processes=4)  # CPU核数
    result = []
    person = ["东邪", "西毒", "南帝", "北丐"]
    result.append(pool.apply_async(fc1, (person[0],)))
    result.append(pool.apply_async(fc2, (person[1],)))
    result.append(pool.apply_async(fc3, (person[2],)))
    result.append(pool.apply_async(fc4, (person[3],)))
    pool.close()
    pool.join()
    print("全部OK....")

多线程队列

import multiprocessing as mp

def job(x):
    res = 0
    for i in range(4):
        res += i
    x.put(res)

if __name__ == "__main__":
    # 定义一个多线程队列,用来存储结果
    q = mp.Queue()
    # 定义两个线程函数,用来处理同一个任务
    # Process / Thread
    p1 = mp.Process(target=job, args=(q,))
    p2 = mp.Process(target=job, args=(q,))
    # 分别启动、连接两个线程
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    fc1 = q.get()
    fc2 = q.get()
    print(fc1 + fc2)

进程锁

# 防止不同进程之间抢占共享资源
import multiprocessing as mp
import time

def job(v, num, l):
    l.acquire()  # 锁住
    for _ in range(5):
        time.sleep(1)
        v.value += num  # 获取共享内存
        print("value=", v.value)
    l.release()  # 释放

def multicore():
    lock = mp.Lock()  # 定义一个进程锁
    value = mp.Value("i", 20)  # 定义共享内存
    p1 = mp.Process(target=job, args=(value, 1, lock))  # 需要将lock传入
    p2 = mp.Process(target=job, args=(value, 3, lock))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == "__main__":
    multicore()

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vip飞梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值