0601-进程池与线程池

可重复利用的线程

from threading import Thread
from queue import Queue
import time


def func1():
   time.sleep(1)
   print('任务一完成')


def func2(*args,**kwargs):
   time.sleep(2)
   print('任务二完成',args,kwargs)


class MyThread(Thread):
   def __init__(self,queue):
      super().__init__()
      self.queue = queue
      self.daemon = True  # 守护线程

   def run(self):
      while True:
         func,args,kwargs = self.queue.get()  # 从队列中拿到函数名
         func(*args,**kwargs)  # 调用函数
         self.queue.task_done()  # 计数器减一

   def apply_async(self,func,*args,**kwargs):
      # 往队列中添加任务(把参数也丢进去)  注意:是元组(不可变)
      self.queue.put( (func,args,kwargs) )

   def join(self):
      # 如果队列计数器不为0 等待为0(等队列元素全被put)
      self.queue.join()  # 阻塞 直到队列中没有数据


queue = Queue()
my_thread = MyThread(queue)

# task_list = [func1,func2]
#
# for func in task_list:
#  my_thread.apply_async(func,)

my_thread.apply_async(func1)
my_thread.apply_async(func2,1,2,a=1,b=2)

my_thread.start() # 调用run()
my_thread.join() # 调用自定义的join()
ssh://pyvip@127.0.0.1:1234。。。
任务一完成
任务二完成 (1, 2) {'b': 2, 'a': 1}

Process finished with exit code 0

线程池的简单实现

主线程: 相当于生产者,

只管向线程池提交任务,并不关心线程池是如何执行任务的。

因此,并不关心是哪一个线程执行的这个任务。

线程池: 相当于消费者,负责接收任务,

并将任务分配到一个空闲的线程中去执行。

1530886537507

from threading import Thread
from queue import Queue
import time


def func1():
   time.sleep(1)
   print('任务一完成')


def func2(*args, **kwargs):
   time.sleep(2)
   print('任务二完成', args, kwargs)


class MyThreadPool():
   def __init__(self, n):
      self.queue = Queue()
      for i in range(n):   # 守护线程
         Thread(target=self.worker, daemon=True).start()   # 注意start

   def worker(self):
      while True:
         func,args,kwargs = self.queue.get()   # 从队列中拿到函数名
         func(*args, **kwargs)  # 调用函数
         self.queue.task_done()  # 计数器减一

   def apply_async(self, func, *args, **kwargs):
      self.queue.put( (func,args,kwargs) ) # 往队列中添加任务

   def join(self):
      self.queue.join() # 阻塞 直到队列中没有数据


pool = MyThreadPool(4) # 线程池里有4个线程准备
pool.apply_async(func1) # 提交任务
pool.apply_async(func2, 1, 2, c=3, d=4)
pool.join()
ssh://pyvip@127.0.0.1:1234/。。。。
任务一完成
任务二完成 (1, 2) {'d': 4, 'c': 3}

Process finished with exit code 0

Python自带池

内置线程池

from multiprocessing.pool import ThreadPool
import time


def func1():
   time.sleep(1)
   print('任务一完成')


def func2(*args, **kwargs):
   time.sleep(2)
   print('任务二完成', args, kwargs)


pool = ThreadPool(4)  # 线程池里有4个线程准备

pool.apply_async(func1)  # 提交任务
pool.apply_async(func2, args=(1, 2), kwds={'a': 1, 'b': 2})

pool.close()  # 关闭线程池 不允许再提交任务

pool.join()  # 阻塞 等待线程池里的任务执行完成 再继续运行
任务一完成
任务二完成 (1, 2) {'b': 2, 'a': 1}

内置的进程池

from multiprocessing import Pool
import time


def func1():
   time.sleep(1)
   print('任务一完成')


def func2(*args, **kwargs):
   time.sleep(2)
   print('任务二完成', args, kwargs)


pool = Pool(4)
pool.apply_async(func1)
pool.apply_async(func2, args=(1, 2), kwds={'a': 1, 'b': 2})
pool.close()
pool.join()
任务一完成
任务二完成 (1, 2) {'b': 2, 'a': 1}

池的操作

操作一: close - 关闭提交通道,不允许再提交任务

操作二: apply_async – 向池中提交任务

操作三: terminate - 中止进程池,中止所有任务

from multiprocessing import Pool
import time


def func():
   time.sleep(2)
   print('hhAH')


pool = Pool(2)
pool.apply_async(func)
pool.close()
pool.join()
ssh://pyvip@127.0.0.1:1234。。。
hhAH

Process finished with exit code 
from multiprocessing import Pool
import time


def func():
   time.sleep(2)
   print('hhAH')


pool = Pool(2)
pool.apply_async(func)
pool.close()
pool.terminate()
pool.join()
ssh://pyvip@127.0.0.1:1234。。。

Process finished with exit code 0

使用池来实现并发服务器

使用线程池来实现并发服务器

import socket
from multiprocessing.pool import ThreadPool


server = socket.socket()
server.bind(('0.0.0.0',8889))
server.listen(100)


# 消费者
def worker(conn):
    while True:
        try:
            data = conn.recv(1024)
            if data:
                print(data.decode())
                conn.send(data)
            else:
                conn.close()
                break
        except Exception as e:
            print(e)
            conn.close()
            break


# 生产者
pool = ThreadPool(4)
while True:
    conn, addr = server.accept()
    pool.apply_async(worker, args=(conn,))
    # 不需要join  消费者是while TRUE  不会结束。
import socket

client = socket.socket()
client.connect(('127.0.0.1',8880))

while True:
   data = input('请输入:')

   if data:
      client.send(data.encode())
      print(client.recv(1024).decode())
   else:
      break

client.close()

使用进程池来实现并发服务器

import socket

from multiprocessing import Pool

server = socket.socket()
server.bind(('0.0.0.0',8888))
server.listen(100)


# 消费者
def worker(conn):
   while True:
      try:
         data = conn.recv(1024) # 拿池里的conn
         if data:
            print(data.decode())
            conn.send(data)
         else:
            conn.close()
            break
      except Exception as e:
         print(e)
         conn.close()
         break


# 生产者

# 池里只能有4个线程 并发量4  同时可以有4个客户端来连接(除非有客户端关闭连接)
pool = Pool(4)
while True:
   conn, addr = server.accept() # 生成对等连接套接字
   pool.apply_async(worker, args=(conn,)) # 把对等连接套接字conn丢进线程池里  池满了会阻塞
   # 不需要join  消费者是while TRUE  不会结束。
import socket

client = socket.socket()
client.connect(('127.0.0.1',8888))

while True:
    data = input('请输入:')

    if data:
        client.send(data.encode())
        print(client.recv(1024).decode())
    else:
        break

client.close()

使用进程池+线程池来实现并发服务器

import socket
from multiprocessing import Pool, cpu_count  # 进程池
from multiprocessing.pool import ThreadPool  # 线程池

server = socket.socket()
server.bind(('0.0.0.0',8888))
server.listen(5)


# 消费者
def worker(conn):
   while True:
      try:
         data = conn.recv(1024)
         if data:
            print('收到:',data.decode())
            conn.send(data)
         else:
            conn.close()
            break
      except Exception as e:
         print(e)
         conn.close()
         break


# 生产者
def worker_process(server):
   # 每一个进程监听客户端连接 不停地生成对等连接套接字 处理消息
   pool = ThreadPool(cpu_count() * 2)  # 创建线程池 开cpu*2个线程
   # 一个进程不停的等待客户端建立连接
   while True:
      # 多个进程accept等人连接 有人连接就把对等连接套接字丢进线程池里
      # 每一个进程监听客户端连接 不停地生成对等连接套接字 处理消息
      conn, addr = server.accept()  # 生成对等连接套接字
      pool.apply_async(worker, args=(conn,))  # 把对等连接套接字丢进线程池


# 2个进程 2个生产者 生成监听套接字 丢进进程池里 生成等连接套接字 丢进线程池里
n = cpu_count()  # 打印当前电脑cpu个数n 2
process_pool = Pool(n)  # 创建进程池 开n个进程 进程处理连接
for i in range(n):
   #  把监听套接字  任务(建立连接 处理消息)  丢进进程池
   process_pool.apply_async(worker_process, args=(server,))

process_pool.close()  # 关闭池
process_pool.join()  # 等待池里面的任务执行完

开2个进程 每个进程开4个线程 故可以同时连接8个客户端

import socket

client = socket.socket()
client.connect(('127.0.0.1',8888))

while True:
   data = input('请输入:')

   if data:
      client.send(data.encode())
      print(client.recv(1024).decode())
   else:
      break

client.close()

没注释的

from multiprocessing.pool import ThreadPool
from multiprocessing import Pool,cpu_count
import socket

server = socket.socket()
server.bind(('0.0.0.0',8889))
server.listen(5)


def worker(conn):
   while True:
      try:
         data = conn.recv(1024)
         if data:
            print('data: ',data.decode())
            conn.send(data)
         else:
            conn.close()
            break
      except Exception as e:
         print(e)
         conn.close()
         break


def worker_process(server):
   thread_pool = ThreadPool(cpu_count() * 2)
   while True:
      conn, addr = server.accept()
      thread_pool.apply_async(worker, args=(conn,))


n = cpu_count()
process_pool = Pool(n)

for i in range(n):
   process_pool.apply_async(worker_process,args=(server,))

process_pool.close()
process_pool.join()

作业:实现一个基于多进程与多进程的并发服务器。

即 使用进程池+线程池来实现并发服务器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值