درک “Async` ،` .ait` و `block_on ()` در زنگ زدگی (با نمونه های واقعی)

به عنوان یک برنامه نویس Rust Systems ، ممکن است شما اغلب به مفاهیمی مانند آن بپردازید async
با .await
وت tokio::runtime::block_on()
بشر اینها ابزارهای اساسی برای نوشتن برنامه های کارآمد و غیر مسدود کننده هستند-اما آنها نیز اغلب توسط مبتدیان اشتباه درک می شوند.
در این پست وبلاگ ، ما تجزیه خواهیم کرد:
- چه
async
وت.await
در زنگ زدگی - چرا
block_on()
وجود دارد و چه زمانی از آن استفاده می شود - این تفاوت ها با توابع سنتی همزمان (مسدود کردن) متفاوت است
- نمونه های دنیای واقعی با کد
- مقایسه ای از انسداد در مقابل رفتار async
- چند رشته در مقابل async در استفاده از زنگ زدگی عملی
چرا استفاده کنید async
؟
زنگ زدگی async
پشتیبانی شما را قادر می سازد کدی را بنویسید که بتواند عملیات طولانی مدت را انجام دهد-مانند پرونده I/O یا HTTP درخواست هایبدون مسدود کردن کل موضوعبشر
async fn say_hello() {
println!("Hello from async!");
}
برای اجرای این کار ، شما باید استفاده کنید .await
درون یک زمینه async یا با استفاده از آن تماس بگیرید block_on()
اگر در کد همگام سازی هستید:
use tokio::runtime::Runtime;
fn main() {
let rt = Runtime::new().unwrap();
rt.block_on(say_hello());
}
چه می کند block_on()
انجام دهید؟
block_on()
روشی است که یک تابع async را از یک زمینه همزمان اجرا می کند، مانند main()
بشر این خواهد بود:
- کار Async را شروع کنید
- نخ را تا زمان انجام کار مسدود کنید
این امر به ویژه در برنامه های CLI یا آزمایش جایی که نمی خواهید کل برنامه شما async باشد مفید است.
مقایسه همگام سازی در مقابل async
🔴 مسدود کردن (همزمان)
fn fetch_data() -> String {
std::thread::sleep(std::time::Duration::from_secs(2));
"Result".to_string()
}
fn main() {
let result = fetch_data();
println!("{}", result); // Takes ~2 seconds
}
✅ async (غیر مسدود کننده)
use tokio::time::{sleep, Duration};
async fn fetch_data() -> String {
sleep(Duration::from_secs(2)).await;
"Result".to_string()
}
#[tokio::main]
async fn main() {
let result = fetch_data().await;
println!("{}", result); // Also takes ~2 seconds
}
پس چه فایده ای دارد؟
✨ async با همزمانی می درخشد
بیایید هنگام دویدن تفاوت را ببینیم دو وظایف
🔴 همزمان
fn task1() -> String {
std::thread::sleep(std::time::Duration::from_secs(2));
"Task 1".to_string()
}
fn task2() -> String {
std::thread::sleep(std::time::Duration::from_secs(2));
"Task 2".to_string()
}
fn main() {
let start = std::time::Instant::now();
println!("{} and {}", task1(), task2());
println!("Elapsed: {:?}", start.elapsed()); // ~4s
}
✅ ناهمزمان
use tokio::time::{sleep, Duration};
async fn task1() -> String {
sleep(Duration::from_secs(2)).await;
"Task 1".to_string()
}
async fn task2() -> String {
sleep(Duration::from_secs(2)).await;
"Task 2".to_string()
}
#[tokio::main]
async fn main() {
let start = std::time::Instant::now();
let (a, b) = tokio::join!(task1(), task2());
println!("{} and {}", a, b);
println!("Elapsed: {:?}", start.elapsed()); // ~2s
}
با tokio::join!
، توابع async همزمان دویدن، کاهش زمان کل به طور چشمگیری.
🧵 نمونه های چند رشته ای در دنیای واقعی
علاوه بر Async ، Rust نیز پشتیبانی می کند چند رشته، که برای کارهای محدود به CPU ایده آل است.
🧶 استفاده std::thread
برای همزمانی
use std::thread;
fn main() {
let handle1 = thread::spawn(|| {
println!("Thread 1 doing work");
});
let handle2 = thread::spawn(|| {
println!("Thread 2 doing work");
});
handle1.join().unwrap();
handle2.join().unwrap();
}
این بهترین برای:
- پردازش پرونده موازی
- محاسبات سنگین (هش ، فشرده سازی و غیره)
- در حال اجرا کارگران پس زمینه
📌 جدول مقایسه
نوع کار | از async استفاده می کنید؟ | از موضوعات استفاده می کنید؟ | نمونه |
---|---|---|---|
تماس API HTTP | ✅ بله | 🚫 نه | پرس و جو کیف پول utxos |
خواندن پرونده (بزرگ) | ✅ اغلب | ✅ گاهی اوقات | بارگیری blockchain db |
گزینه های رمزنگاری | 🚫 نه | ✅ بله | امضای معاملات |
شنوندگان رویداد | ✅ بله | 🚫 نه | گوش دادن به بلوک های جدید |
🧠 چه موقع از چه چیزی استفاده کنیم؟
هدف | استفاده کردن |
---|---|
اسکریپت ساده یا تماس یک طرفه | block_on() |
اسکنر کیف پول چند درخواست |
.await با join!() یا spawn()
|
مشاغل هشویی محدود به CPU |
std::thread یا rayon
|
HTTP/سرور وب یا ربات | کاملاً آدمک main()
|
افکار نهایی
با استفاده از async
در Rust به شما امکان می دهد کار بیشتری را با موضوعات کمتری انجام دهید. block_on()
پلی برای استفاده است async
در محیط های همگام سازی مانند ابزارهای CLI. در همین حال ، MultitHreading هنوز هم قدرتمند و گاهی اوقات مناسب تر برای کارهای CPU یا واقعاً موازی است.
اگر در حال ساختن چیزی شبیه به برنامه کیف پول که UTXOS را واگذار می کند یا معاملات را پخش می کند ، با استفاده از توابع ASYNC برای HTTP و درخواست های شبکه یک ضرورت برای کارآیی اما برای امضای رمزنگاری یا نمایه سازی پس زمینه ، چند نخ ممکن است بهتر باشدبشر
درک این تجارت قدرت نوشتن را به شما می دهد کاربردهای با کارایی بالا ، مقیاس پذیربشر