首页 > 系统相关 >进程池、线程池、协程

进程池、线程池、协程

时间:2022-11-21 20:56:39浏览次数:40  
标签:__ 协程 线程 IO time 进程 import

进程池、线程池、协程

进程池与线程池

硬件是有极限的,我们不可能一直在一台计算机上无限的创建新的进程和线程,虽然软件逻辑上我们可以无限的创建,但是一旦这么做了,我们的计算机可能到达承受不了的极限,最后崩溃到无法执行任何程序的地步。

所以为了限制进程和线程的无限创建(如我们写过的来一个客户端就开个进程去服务他),有了池的概念。

  • 进程池/线程池:提前创建好固定数量的进程/线程供后续程序的调用,超出数量则等待

代码实现进程池和线程池

from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import os
import time
import random

# 1.产生含有固定数量线程的线程池
# pool = ThreadPoolExecutor(10)
pool = ProcessPoolExecutor(5)  # 产生进程池
# 查看源码可以看见这个类可以不写数字产生对象,这个数字是池的容量
# 如果不指定就根据cpu的参数来自动获取对应合适的数量


def task(n):
    print('task is running')
    time.sleep(random.randint(1, 3))

if __name__ == '__main__':
    # 2.将任务提交给线程池即可
    for i in range(20):
        pool.submit(task, 123)  # 朝线程池提交任务
        
"""
运行的结果会成批的打印,按照原本的开进程线程的方式,相当于同时开启了20个进程或线程
但现在当提交的任务达到进程或线程达到池的上限,新的任务就会等待某个任务线程执行完再去争夺线程\进程
"""

回调机制

回调机制指当提交到进程\线程池的任务结束时可以触发另一个函数的运行,并且将自己的任务对象传入函数以便它进行处理,如可以通过任务对象.result()的方式拿到任务函数的返回值。

from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import os
import time
import random

# 1.产生含有固定数量线程的线程池
# pool = ThreadPoolExecutor(10)
pool = ProcessPoolExecutor(5)


def task(n):
    print('task is running')
    time.sleep(random.randint(1, 3))
    return '我是task函数的返回值'  # 拿到返回值


def func(self):
    print('from func', self.result())  # 在这里仍然异步的处理返回值。

if __name__ == '__main__':
    # 2.将任务提交给线程池即可
    for i in range(20):
        res = pool.submit(task, 123)  # 朝线程池提交任务,返回任务对象
        # print(res.result())  # 不能直接获取,相当于变成串行
        res.add_done_callback(func)  # 提交的任务可以调用这个函数来触发回调,当任务结束时调用func函数

协程

是独立于操作系统的进程线程外开发的实现并发的方式,也就是说可以通过单线程实现并发。

我们知道进程和线程是通过碰到IO时切换加保存程序状态的方式实现异步的,现在我们让程序帮我们检测IO,当碰到IO时就去做当前线程的其他代码,当那个IO结束时就处理相应的代码段,这个过程也一样实现了异步并发。这样做让操作系统永远不知道我们进入了IO,也可以提升我们程序对CPU的占用率。

协程代码实现

import time
from gevent import monkey;

monkey.patch_all()  # 固定编写 用于检测所有的IO操作(猴子补丁)
from gevent import spawn


def func1():
    print('func1 running')
    time.sleep(3)
    print('func1 over')


def func2():
    print('func2 running')
    time.sleep(5)
    print('func2 over')


if __name__ == '__main__':
    start_time = time.time()
    # func1()
    # func2()
    s1 = spawn(func1)  # 检测代码 一旦有IO自动切换(执行没有io的操作 变向的等待io结束)
    s2 = spawn(func2)
    s1.join()
    s2.join()
    print(time.time() - start_time)  # 串行8.01237154006958   协程 5.015487432479858

协程实现并发服务端

import socket
from gevent import monkey;monkey.patch_all()  # 固定编写 用于检测所有的IO操作(猴子补丁)
from gevent import spawn


def communication(sock):
    while True:
        data = sock.recv(1024)  # IO操作
        print(data.decode('utf8'))
        sock.send(data.upper())


def get_server():
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    while True:
        sock, addr = server.accept()  # IO操作
        spawn(communication, sock)  # 异步的接收用户输入

s1 = spawn(get_server)  # 创建socket套接字
s1.join()

上述代码中,如果任务中含IO操作,则就可以将其传入spwan让其进行协程处理。

ps:如果我们想要尽可能的提高程序的并发量,则要多开进程,进程下开多线程,线程下开协程。

标签:__,协程,线程,IO,time,进程,import
From: https://www.cnblogs.com/Leethon-lizhilog/p/16913177.html

相关文章

  • 线程相关知识
    线程理论进程 进程其实是资源单位,表示一块内存空间线程 线程才是执行单位,表示真正的代码指令我们可以将进程比喻是车间,线程是车间里面的流水线一个进程内部至少含有......
  • 进程池与线程池
    进程和线程是不可以无限制的创建因为硬件的发展赶不上软件,有物理极限,如果我们在编写代码的过程中无限制的创建进程或者线程会导致计算机崩溃池 降低程序的执行效率,但是......
  • python之路32 网络并发线程方法 线程池 协程
    多进程实现TCP服务端并发服务端:importsocketfrommultiprocessingimportProcessdefget_server():server=socket.socket()server.bind(('127.0.0.1'......
  • 进入python的世界_day35_网络编程——线程相关知识、GIL锁,互斥锁、event事件、池子、
    上周五作业——多进程实现TCP服务端并发#服务端importsocketfrommultiprocessingimportProcessdefget_server():server=socket.socket()server.bi......
  • 互斥锁、线程
    今日内容概要多进程实现TCP服务端并发互斥锁代码实操线程理论创建线程的多种方式线程join方法守护线程线程诸多方法GIL全局解释器锁今日内容详情多进程实......
  • 并发编程3 线程
    多进程实现TCP服务端并发importsocketfrommultiprocessingimportProcessdefget_server():server=socket.socket()server.bind(('127.0.0.1',8081)......
  • C# 简单实现线程池
    NET6环境开发 实现线程数量,任务队列,非核心线程,及核心线程活跃时间的管理。namespaceCustomThreadPool;///<summary>///线程池类///</summary>publicclassT......
  • 多线程与线程池知识点
    多线程https://www.cnblogs.com/empty-me/p/15664024.htmlJava多线程:向线程传递参数的三种方法......
  • 线程理论
    今日内容详细互斥锁代码实操锁:建议只加载操作数据的部分否则整个程序的效率会很低defsearch(name):withopen(r'joyce.txt','r',encoding='utf8')asf:......
  • 多进程实现TCP服务端并发、互斥锁、线程及代码实现、GIL全局解释器锁、信号量、event
    目录一、多进程实现TCP服务端并发二、互斥锁代码实操1、互斥锁的概念2、互斥锁的使用3、死锁现象4、小结三、线程理论进程线程线程简介为什么要使用多线程?多线程概念多进......