阻塞 vs 非阻塞:程序等待的兩種哲學

當程序需要等待外部操作時,是應該"干等"還是"邊等邊干"?為什么有些程序會卡住不動,而另一些卻能流暢運行?這一切都取決于阻塞非阻塞的編程選擇!本文將為你揭示這兩種模式的本質區別!

一、生活比喻:超市結賬的兩種方式

阻塞式等待:單通道排隊

在這里插入圖片描述

非阻塞式等待:取號系統

在這里插入圖片描述

二、核心概念解析

1. 阻塞(Blocking):必須等待

在這里插入圖片描述

特點:

  • ? 程序執行被暫停
  • ? 必須等待操作完成
  • 🧘 期間CPU不能做其他事

2. 非阻塞(Non-blocking):邊等邊做

在這里插入圖片描述

特點:

  • 🚦 調用立即返回
  • 🔄 需要主動輪詢結果
  • 💻 CPU可執行其他任務

三、技術原理深度解析

操作系統層面的區別

在這里插入圖片描述

四、代碼對比:文件讀取示例

阻塞式讀取(Python)

print("開始讀取文件...")  
with open('large_file.txt', 'r') as f:  data = f.read()  # 程序在此阻塞直到讀取完成  
print(f"讀取完成,大小:{len(data)}字節")  
print("程序繼續執行")  # 輸出順序:  
# 開始讀取文件...  
# (長時間等待...)  
# 讀取完成,大小:1024000字節  
# 程序繼續執行  

非阻塞式讀取(Python使用os模塊)

import os  
import time  print("開始非阻塞讀取...")  
fd = os.open('large_file.txt', os.O_RDONLY | os.O_NONBLOCK)  while True:  try:  # 嘗試讀取(非阻塞)  data = os.read(fd, 4096)  if data:  print(f"讀取到 {len(data)} 字節數據")  else:  # 文件結束  break  except BlockingIOError:  print("數據未就緒,處理其他任務...")  # 模擬其他工作  time.sleep(0.1)  os.close(fd)  
print("程序結束")  # 輸出可能:  
# 開始非阻塞讀取...  
# 數據未就緒,處理其他任務...  
# 數據未就緒,處理其他任務...  
# 讀取到 4096 字節數據  
# 讀取到 4096 字節數據  
# ...  

五、核心區別對比表

特性阻塞 🔒非阻塞 🔓
調用返回操作完成后返回立即返回
程序狀態掛起等待繼續運行
CPU利用等待期間CPU空閑CPU可處理其他任務
編程復雜度簡單直觀較復雜(需輪詢/回調)
響應性能延遲高響應更及時
資源消耗線程/進程占用內存單線程可處理多任務
適用場景簡單應用、順序處理高并發、實時系統
典型代表標準文件讀寫select/poll/epoll

六、性能影響:阻塞 vs 非阻塞

服務器并發能力對比

在這里插入圖片描述

資源消耗對比

在這里插入圖片描述

七、實際應用場景分析

何時使用阻塞?

在這里插入圖片描述

典型案例:

  • 數據分析批處理
  • 命令行工具
  • 單用戶桌面應用

何時使用非阻塞?

在這里插入圖片描述

典型案例:

  • Web服務器(Nginx,Node.js)
  • 聊天應用
  • 股票交易系統
  • 游戲服務器

八、現代非阻塞技術棧

主流語言的非阻塞實現

語言阻塞API非阻塞API框架
Pythonopen()/read()asyncio/aiofilesFastAPI, Sanic
JavaInputStreamNIONetty, Spring WebFlux
C++fstreamboost::asioBeast, Seastar
Gogoroutine+channelGin, Fiber
Node.jsfs.readFile+回調Express, Koa

非阻塞設計模式

在這里插入圖片描述

九、阻塞與非阻塞的混合使用

生產者-消費者模式

在這里插入圖片描述

代碼示例(Python queue):

import threading  
import queue  def producer(q):  for i in range(5):  q.put(i)  # 阻塞如果隊列滿  print(f"生產: {i}")  def consumer(q):  while True:  item = q.get()  # 阻塞如果隊列空  print(f"消費: {item}")  q.task_done()  q = queue.Queue(3)  
threading.Thread(target=producer, args=(q,)).start()  
threading.Thread(target=consumer, args=(q,)).start()  

十、未來趨勢:全異步編程

異步/等待(async/await)范式

import asyncio  
import aiohttp  async def fetch(url):  async with aiohttp.ClientSession() as session:  async with session.get(url) as response:  return await response.text()  async def main():  tasks = [  fetch('https://example.com'),  fetch('https://example.org')  ]  results = await asyncio.gather(*tasks)  for i, text in enumerate(results):  print(f"網站{i+1}大小: {len(text)}字節")  asyncio.run(main())  

io_uring:Linux終極異步接口

在這里插入圖片描述

優勢:

  • ? 零拷貝數據傳輸
  • 🚀 批量操作提交
  • 💾 統一文件/網絡I/O接口

十一、總結:選擇指南

決策流程圖

在這里插入圖片描述

黃金法則

  1. I/O密集型應用 → 優先非阻塞
  2. CPU密集型應用 → 阻塞更簡單
  3. 混合型應用 → 線程池+非阻塞I/O
  4. 新項目開發 → 考慮異步優先架構

💡 核心洞見:

  • 阻塞是"不拿到結果不離開"
  • 非阻塞是"先拿號,等會再來問"
  • 選擇取決于應用場景而非技術優劣
  • 現代高并發系統主要依賴非阻塞模型

思考題:為什么數據庫連接池要使用阻塞模式?評論區分享你的見解!

🚀 動手實驗:體驗兩種模式的差異

# 阻塞式下載  
import requests  
response = requests.get('https://example.com')  # 非阻塞式下載(使用aiohttp)  
import aiohttp  
import asyncio  async def async_download():  async with aiohttp.ClientSession() as session:  async with session.get('https://example.com') as resp:  return await resp.text()  asyncio.run(async_download())  

理解阻塞與非阻塞,你就掌握了高效編程的鑰匙!現在就開始在你的項目中應用這些知識吧!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/97896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/97896.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/97896.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 核心操作全解析(用戶 + SHOW+DML+DCL)

MySQL 核心操作全解析(用戶 SHOWDMLDCL) 基于你提供的實操筆記,我們將 MySQL 核心操作拆解為用戶管理、SHOW 查詢命令、DML 數據操作、TRUNCATE 與 DELETE 對比、DCL 權限控制五大模塊,梳理語法邏輯、補充避坑提示,幫…

多語言編碼Agent解決方案(6)-部署和使用指南

部署和使用指南 本指南提供完整的部署和使用說明,幫助您設置后端服務并在VSCode、Eclipse和IntelliJ中使用相應的插件。這個解決方案基于vLLM提供AI編碼輔助,支持英語、中文和日文。 前提條件 操作系統:Linux、macOS或Windows(推薦…

濾波器的三重境界:從信號處理到自動駕駛測試的基石

在自動駕駛的宏大敘事中,我們常常聚焦于人工智能、深度學習、高精地圖等"明星技術"。然而,在這些耀眼的光環背后,有一個低調卻至關重要的"幕后英雄"——濾波器。它不僅是信號處理的工具,更是連接物理世界與數…

Part4.第8章:神經網絡

第8章 激活函數 如果沒有激活函數,不論幾層的神經網絡都是一個線性回歸。激活函數的作用是引入非線性。

nextjs+shadcn+tailwindcss實現博客中的overview

最近在用nextjsshadcntailwindcss練手,實現一個博客。做到了overView這里,可實現如下效果1.首先要安裝tailwindcss,這個在創建項目的時候就安裝了。2.然后安裝shadcn,官網教程:3.代碼如下:import {Card,CardContent } …

Kotlin 高階語法解析

Kotlin 高級語法深度解析1. 協程(Coroutines)1.1 基礎概念1.掛起和恢復2.協程構建器 (Coroutine Builders)3.協程作用域4.調度器1.2 核心用法1.3 實戰示例2. 密封類(Sealed Classes)2.1 定義與特性2.2 模式匹配2.3 應用場景3. 內聯…

9 基于機器學習進行遙感影像參數反演-以隨機森林為例

目錄 1 讀取數據 2 數據預處理 3模型訓練 4模型預測 5精度分析 由于回歸任務的標簽數據獲取比較困難,我們這次用水體指數NDWI來模擬作為回歸任務的標簽,通過隨機森林來擬合回歸NDWI,其計算公式如下: NDWI = (band3 - band5) / (band3 + band5) 實際情況下需要回歸的數…

C++多線程編程:跨線程操作全解析

C中的"線程"通常指單個執行流(如std::thread對象),而"多線程"指程序中同時存在多個這樣的執行流,并涉及它們的創建、管理和同步。實現跨線程操作的核心在于安全地處理共享數據和線程間通信。 以下是實現跨線程…

【腦電分析系列】第13篇:腦電源定位:從頭皮到大腦深處,EEG源定位的原理、算法與可視化

前言腦電信號(Electroencephalography, EEG)是一種非侵入性的神經成像技術,能夠實時捕捉大腦的電活動。然而,頭皮上記錄到的信號是腦源活動經過頭皮、顱骨等介質“模糊”后的投影。想要從這些頭皮EEG信號追溯到大腦深處的電活動&a…

MySQL知識筆記

DATE_ADD(date,INTERVAL expr type) date 參數是合法的日期表達式。expr 參數是您希望添加的時間間隔。多查官方手冊!!命令行啟動和停止sql服務net start 數據庫名; 這是啟動服務命令; 例如:net start Mysql56…

2025算法八股——深度學習——MHA MQA GQA

MHA、MQA、GQA 都是深度學習中注意力機制的相關概念,其中 MHA 是標準的多頭注意力機制,MQA 和 GQA 則是其優化變體,以下是它們的區別、優缺點介紹:區別MHA(多頭注意力):是 Transformer 架構的核…

Vue3》》eslint Prettier husky

安裝必要的依賴 npm install -D eslint eslint/js vue/eslint-config-prettier prettier eslint-plugin-vue 初始化 ESLint 配置 npm init eslint/config// eslint.config.js // 針對 JavaScript 的 ESLint 配置和規則。保持 JavaScript 代碼的一致性和質量 import js from &qu…

Custom SRP - Point and Spot Lights

https://catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-lights/Lights with Limited Influence1 Point Lights1.1 Other Light Data (Point )同方向光一樣,我們支持有限數量的 Other Light.盡管場景中可能有很多 Other Lights,可能有超過光源上限的光源時可見的…

hive數據倉庫的搭建

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄前言一、內嵌模式二、本地模式三、遠程模式前言 HIVE是基于HDFS的數據倉庫,要首先搭建好HADOOP的集群才可以正常使用HIVE,HADOOP集運搭建詳見…

域名SSL證書免費申請lcjmSSL

.-.lcjmSSL(又名“來此加密”)是一個提供免費SSL證書申請的一站式平臺。它支持單域名、多域名以及泛域名證書申請,且單張證書最高可覆蓋100個域名,讓您輕松實現全站HTTPS加密。為什么您的網站必須安裝SSL證書?數據加密…

“能量逆流泵”:一種基于電容陣與開關矩陣的超高效大功率降壓架構

摘要本文提出并驗證了一種面向大功率降壓應用的革命性電源架構——"能量逆流泵"(Energy Inversion Pump, EIP)。該架構摒棄了傳統Buck轉換器中的電感元件,通過高速開關矩陣控制的電容陣列,將高壓側能量以"分時、分…

打造精簡高效的 uni-app 網絡請求工具

在 uni-app 開發中,網絡請求是連接前端與后端的核心橋梁。一個設計良好的請求工具能夠顯著提升開發效率,減少重復代碼。本文將分享一個精簡版的 uni-app 網絡請求工具實現,它保留了核心功能同時保持了足夠的靈活性。設計思路一個優秀的網絡請…

【面試場景題】交易流水表高qps寫入會有鎖等待或死鎖問題嗎

文章目錄一、先明確交易流水表的核心特性二、InnoDB的鎖機制在流水表寫入場景的表現1. 行鎖(Record Lock):基本不涉及2. 間隙鎖(Gap Lock)與Next-Key Lock:幾乎不觸發3. 表鎖:僅在極端場景出現三…

項目部署——LAMP、LNMP和LTMJ

前情提要問:如何通過nginx的反向代理,代理多臺虛擬主機(一臺apache服務器上的虛擬主機)?1.在nginx的配置文件中,將基于域名的訪問改為基于端口的訪問(nginx.conf)upstream daili{ser…

晨曦中,它已勞作:一臺有溫度的機器人如何重塑我們的潔凈日常

清晨六點,城市的輪廓在微光中逐漸清晰。某高端小區的路面上,一臺灰色機身、線條流暢的機器正在安靜地工作。它繞過停靠的車輛,精準地沿著路緣石前進,吸走落葉與塵土,遇到突然竄出的流浪貓時輕巧避讓,仿佛有…