树莓派24/7运行Python串口数据拉取:Cron与APScheduler方案选型咨询
Great question! Let's break down each option and figure out the best fit for your continuous serial data collection task on a Raspberry Pi.
Option 2: Cron-Job – Not Feasible
Let's get this out of the way first: cron is not suitable for your 2-second interval requirement. Cron's smallest scheduling granularity is 1 minute—you can't configure it to run a task every 2 seconds. Even if you tried to work around this (like spawning a long-running process from a cron job), you'd lose cron's core benefit (scheduling) and introduce unnecessary complexity. Save yourself the headache and skip this option entirely.
Option 1: Systemd + APScheduler – Recommended for Flexibility & Reliability
This is a robust, production-grade approach that combines two powerful tools:
- systemd: Handles process management, ensuring your script starts on boot, restarts automatically if it crashes, and runs in the background.
- APScheduler: Provides precise, flexible scheduling (including 2-second intervals) and supports more advanced features if your needs grow (e.g., adding one-time tasks, changing intervals dynamically).
Example Setup:
- Python Script with APScheduler (
serial_poll.py):
import serial from apscheduler.schedulers.background import BackgroundScheduler def read_serial_data(): # Configure your serial port (adjust port/baud rate as needed) ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1) try: data = ser.readline().decode('utf-8').strip() if data: print(f"Received: {data}") # Add your data processing/storage logic here except Exception as e: print(f"Error reading serial data: {e}") finally: ser.close() if __name__ == "__main__": scheduler = BackgroundScheduler() # Schedule the task to run every 2 seconds scheduler.add_job(read_serial_data, 'interval', seconds=2) scheduler.start() # Keep the main thread alive try: while True: pass except (KeyboardInterrupt, SystemExit): scheduler.shutdown()
- Systemd Service File (
/etc/systemd/system/serial-poll.service):
[Unit] Description=Serial Data Polling Service After=multi-user.target [Service] Type=simple User=pi ExecStart=/usr/bin/python3 /home/pi/serial_poll.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
- Enable & Start the Service:
sudo systemctl daemon-reload sudo systemctl enable serial-poll.service sudo systemctl start serial-poll.service
Option 3: Systemd + Python time.sleep() Loop – Lightweight Alternative
If you don't need APScheduler's advanced features, a simple infinite loop with time.sleep(2) is even lighter and avoids adding an extra dependency. This works perfectly for fixed-interval tasks like yours.
Example Script (serial_poll_simple.py):
import serial import time def main(): while True: ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1) try: data = ser.readline().decode('utf-8').strip() if data: print(f"Received: {data}") # Add your data processing/storage logic here except Exception as e: print(f"Error reading serial data: {e}") finally: ser.close() time.sleep(2) if __name__ == "__main__": main()
You can use the same systemd service file as above (just update the ExecStart path to point to this script).
Final Recommendation
- Choose Option 1 (systemd + APScheduler) if you anticipate needing flexible scheduling later (e.g., adjusting intervals, adding other scheduled tasks) or want a more structured approach.
- Choose Option 3 (systemd +
time.sleep()loop) if you prefer minimal dependencies and a simpler setup—this is totally sufficient for your current 2-second polling requirement.
Either way, using systemd is non-negotiable for 7x24 uptime on Raspberry Pi—it ensures your script survives reboots and crashes. Cron is out of the question due to its 1-minute minimum interval.
内容的提问来源于stack exchange,提问作者Marvin Noll

