python 进程(池)、线程(池)
进程、多进程、进程池
进程总概述
进程
from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
多进程(进程池创建)
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__ == '__main__':
print('Parent process %s.' % os.getpid())
p = Pool(3)
for i in range(4):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
解析:
对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
Parent process 87461.
Waiting for all subprocesses done...
Run task 0 (87462)...
Run task 1 (87463)...
Run task 2 (87464)...
Task 1 runs 1.66 seconds.
Run task 3 (87463)... -----------------> task3在某个进程结束时,在创建
Task 2 runs 2.33 seconds.
Task 0 runs 2.54 seconds.
Task 3 runs 2.83 seconds.
All subprocesses done.
进程之间通信
Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:
from multiprocessing import Process, Queue
import os, time, random
# 写数据进程执行的代码:
def write(q):
print('Process to write: %s' % os.getpid())
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
# 读数据进程执行的代码:
def read(q):
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value)
if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()
# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr.terminate()
线程总概述
线程
import time, threading
# 新线程执行的代码:
def loop():
print('thread %s is running...' % threading.current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
线程锁-线程安全(操作同一个变量)
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
global balance
balance = balance + n
balance = balance - n
finally:
# 改完了一定要释放锁:
lock.release()
线程池创建
ThreadPoolExecutor实现
from socket import AF_INET, SOCK_STREAM, socket
from concurrent.futures import ThreadPoolExecutor
def echo_client(sock, client_addr):
'''
Handle a client connection
'''
print('Got connection from', client_addr)
while True:
msg = sock.recv(65536)
if not msg:
break
sock.sendall(msg)
print('Client closed connection')
sock.close()
def echo_server(addr):
pool = ThreadPoolExecutor(128)
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock, client_addr = sock.accept()
pool.submit(echo_client, client_sock, client_addr)
echo_server(('',15000))
手动创建你自己的线程池, 通常可以使用一个Queue来轻松实现
from socket import socket, AF_INET, SOCK_STREAM
from threading import Thread
from queue import Queue
def echo_client(q):
'''
Handle a client connection
'''
sock, client_addr = q.get()
print('Got connection from', client_addr)
while True:
msg = sock.recv(65536)
if not msg:
break
sock.sendall(msg)
print('Client closed connection')
sock.close()
def echo_server(addr, nworkers):
# Launch the client workers
q = Queue()
for n in range(nworkers):
t = Thread(target=echo_client, args=(q,))
t.daemon = True
t.start()
# Run the server
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock, client_addr = sock.accept()
q.put((client_sock, client_addr))
echo_server(('',15000), 128)
python 进程(池)、线程(池)的更多相关文章
- python并发编程-进程池线程池-协程-I/O模型-04
目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...
- Python学习之GIL&进程池/线程池
8.6 GIL锁** Global interpreter Lock 全局解释器锁 实际就是一把解释器级的互斥锁 In CPython, the global interpreter lock, or ...
- Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池
Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...
- Python标准模块--concurrent.futures 进程池线程池终极用法
concurrent.futures 这个模块是异步调用的机制concurrent.futures 提交任务都是用submitfor + submit 多个任务的提交shutdown 是等效于Pool ...
- concurrent.futures模块(进程池/线程池)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Python-GIL 进程池 线程池
5.GIL vs 互斥锁(*****) 1.什么是GIL(Global Interpreter Lock) GIL是全局解释器锁,是加到解释器身上的,保护的就是解释器级别的数据 (比如垃圾回收的数据) ...
- 13 并发编程-(线程)-异步调用与回调机制&进程池线程池小练习
#提交任务的两种方式 #1.同步调用:提交完任务后,就在原地等待任务执行完毕,拿到结果,再执行下一行代码,导致程序是串行执行 一.提交任务的两种方式 1.同步调用:提交任务后,就在原地等待任务完毕,拿 ...
- python day 20: 线程池与协程,多进程TCP服务器
目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...
- Python之路——线程池
1 线程基础 1.1 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2 线程同步——锁 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样,其实Python中是伪多线程).但是当线程 ...
- 并发编程---线程queue---进程池线程池---异部调用(回调机制)
线程 队列:先进先出 堆栈:后进先出 优先级:数字越小优先级越大,越先输出 import queue q = queue.Queue(3) # 先进先出-->队列 q.put('first') ...
随机推荐
- Goland远程连接Linux开发调试
参考链接: https://blog.csdn.net/huwh_/article/details/77879152?utm_source=blogxgwz3 https://baijiahao.ba ...
- neutron plugin 笔记
neutron-plugin 分为 core-plugin 和 service-plugin 两类 L2-L3称为core plugin,包含network.subnet.portL4-L7称为ser ...
- kubectl 安装
下载kubectl二进制文件curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.10.0/bin/linux/a ...
- Qt 最简单的多线程方法QtConcurrent::run()
Qt 最简单的多线程方法QtConcurrent::run()(转载) 最近编写了一个软件,没有考虑多线程的问题,编好以后,软件在执行计算的时候,鼠标响应有时候会延迟,但是完全能用,考虑到后续随着计算 ...
- 2020.08.23 瞎扯周记之论短暂假期(QAQ)内要不要睡午觉
蒟蒻的假期都是很短暂的嘛 作为一只合格的蒟蒻 假期自然是很短暂的QAQ 只有短短的26h93360s(手动微笑) 总体来讲 假期只有两件事要干: 1.满足人体自身需求 2.满足作业需求 2.5.摸鱼 ...
- composer源码简单分析(一)
composer分析(一) 本文内容 基于PSR-4规范的自动加载 请结合文档和下面的代码注释 spl_autoload_register php闭包Closure简单用法(大体使用情景: 生成回调提 ...
- Android开发之开源框架OKHTTP的Get请求代码,得到json字符串方法
<span style="white-space:pre"> </span><pre name="code" class=&q ...
- 攻防世界——web新手练习区解题总结<3>(9-12题)
第九题simple_php: 看题目说是php代码,那必定要用到php的知识,让我们先获取在线场景,得到如下网页 仔细看这个代码,意思大概是: 1.当a==0且a为真时输出flag1 2.当b为数字退 ...
- Node中间层浅认知
Node中间层允许前端来做网站路由.页面渲染.SEO优化,对以往从来不接触这些内容的前端选手来说,正是锻炼我们网站架构的好机会.另外,这也是一次深入了解Node的好机会,准备好迎接即将到来的前端工程化 ...
- openssl1.0在mac下的编译安装(踩坑精华)
之前做了一次brew版本升级,然后用pip3安装的一个python命令就无法执行了(涉及到openssl库),执行就会报一个错误. ImportError: dlopen(/usr/local/Cel ...