cratosw

生产者-消费者

生产者-消费者

生产者-消费者模式常用于在线程间分发工作:数据由生产者线程产生,再交给消费者线程处理, 通常不需要直接共享同一块可变状态,也就减少了锁竞争。

.NET 对该模式支持很丰富。最基础场景下可使用 System.Collections.Concurrent.BlockingCollection

using System;
using System.Threading;
using System.Collections.Concurrent;

var messages = new BlockingCollection<string>();
var producer = new Thread(() =>
{
    for (var n = 1; n < 10; n++)
        messages.Add($"Message #{n}");
    messages.CompleteAdding();
});

producer.Start();

// main 线程作为消费者
foreach (var message in messages.GetConsumingEnumerable())
    Console.WriteLine(message);

producer.Join();

Rust 中可通过 channel 实现同样模式。标准库最常用的是 mpsc::channel (多生产者,单消费者):

use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    let producer = thread::spawn(move || {
        for n in 1..10 {
            tx.send(format!("Message #{}", n)).unwrap();
        }
    });

    // main 线程作为消费者
    for received in rx {
        println!("{}", received);
    }

    producer.join().unwrap();
}

和 Rust 的 channel 类似,.NET 也有 System.Threading.Channels。 不过它主要面向 async/await 场景。Rust 生态中更偏异步友好的 channel 可使用 Tokio 提供的实现,见 tokio channels

On this page