基于SimPy的有限缓冲无丢包队列模拟:数据包Departure实现咨询
Let’s break down the fixes you need into two key, easy-to-implement parts—finite buffer setup and departure/server logic—with code examples that build on your existing work.
1. Finite Buffer Implementation
SimPy’s Store class is designed for queueing, and it natively supports finite capacity. Instead of using the default infinite Store, just specify the capacity parameter when creating it. When the buffer is full, any attempt to add a packet will automatically block (wait) until space opens up—exactly what you need for "no drop, just wait" behavior.
Key Code Change:
# Create a finite buffer (adjust capacity to your desired queue size) buffer = simpy.Store(env, capacity=5)
When your arrival process runs yield buffer.put(packet), it will pause the arrival until there’s an empty slot. No extra code needed for waiting—SimPy handles the blocking for you.
2. Departure/Server Process
To handle packet departure, you need a dedicated server process that runs continuously: pulling packets from the buffer, processing them, and marking them as departed. Here’s how to build it:
Step-by-Step Server Logic:
- Run an infinite loop (so the server never stops processing).
- Wait for a packet to become available in the buffer with
yield buffer.get()(blocks until a packet is ready). - Calculate processing time using your fixed packet length (1250 bytes) and your system’s service rate (e.g., bits per second).
- Simulate processing with
yield env.timeout(processing_time). - After processing completes, log the departure event (you can track wait times here too).
Example Server Process Code:
def server(env, buffer, service_rate_bps): while True: # Wait for a packet to pull from the buffer packet = yield buffer.get() print(f"Packet {packet['id']} starts processing at {env.now:.2f}") # Calculate processing time: convert bytes to bits, divide by service rate processing_time = (packet['length'] * 8) / service_rate_bps yield env.timeout(processing_time) # Log departure and total wait time (arrival to departure) total_wait = env.now - packet['arrival_time'] print(f"Packet {packet['id']} departed at {env.now:.2f} (total wait: {total_wait:.2f}s)")
3. Full Integrated Simulation
Here’s a complete example tying everything together, which you can adapt to your existing code:
import simpy import random # Customize these parameters to match your simulation needs AVG_INTER_ARRIVAL = 2.0 # Average time between packet arrivals (seconds) PACKET_LENGTH = 1250 # Fixed packet length (bytes) SERVICE_RATE = 1_000_000 # Service rate (bits per second) BUFFER_CAPACITY = 5 # Finite buffer size SIM_DURATION = 100 # How long to run the simulation (seconds) def packet_arrival(env, buffer): packet_id = 0 while True: # Generate exponential inter-arrival time inter_arrival = random.expovariate(1/AVG_INTER_ARRIVAL) yield env.timeout(inter_arrival) packet_id += 1 packet = { 'id': packet_id, 'length': PACKET_LENGTH, 'arrival_time': env.now } print(f"Packet {packet_id} arrived at {env.now:.2f}") # Add to buffer (blocks if full) yield buffer.put(packet) print(f"Packet {packet_id} added to buffer at {env.now:.2f}") def server(env, buffer): while True: packet = yield buffer.get() print(f"Packet {packet['id']} starts processing at {env.now:.2f}") processing_time = (packet['length'] * 8) / SERVICE_RATE yield env.timeout(processing_time) total_wait = env.now - packet['arrival_time'] print(f"Packet {packet['id']} departed at {env.now:.2f} (total wait: {total_wait:.2f}s)") def run_simulation(): env = simpy.Environment() # Create finite buffer buffer = simpy.Store(env, capacity=BUFFER_CAPACITY) # Start both arrival and server processes env.process(packet_arrival(env, buffer)) env.process(server(env, buffer)) # Run the simulation env.run(until=SIM_DURATION) if __name__ == "__main__": run_simulation()
Quick Customization Tips:
- Tweak
BUFFER_CAPACITYto set your desired finite queue size. - Adjust
SERVICE_RATEto match your system’s processing speed (in bits per second). - Add more metrics (like average queue length) by tracking variables in the processes (e.g., count how many packets are in the buffer at each event).
内容的提问来源于stack exchange,提问作者fieq.fikri

