You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Python多线程脚本启动后停止执行问题求助

Hey Sara, let's fix your thread + Bluetooth issue!

From what you've described, your script is freezing after starting the start_laps thread because one of two common gotchas is blocking your main thread from continuing to listen for Bluetooth data. Let's break this down and fix it step by step.

The Most Likely Culprits

1. You're accidentally waiting for the thread to finish (join() mishap)

If you called lap_thread.join() right after starting the thread, your main thread will grind to a halt until the start_laps thread completes. Since start_laps is probably running a loop (to handle lap tracking), this means your main thread will never get back to listening for new Bluetooth commands.

2. Your Bluetooth listening logic isn't in a persistent loop

Bluetooth's recv() method is blocking by default—it waits until data comes in before moving on. If your main thread only runs the listen logic once (instead of looping), it'll stop after the first data packet, even if you started a thread.

Fixes You Can Implement Right Away

1. Ditch unnecessary join() and keep the main thread listening

Wrap your Bluetooth data reception in an infinite loop, and start the thread without forcing the main thread to wait for it. Here's a revised code example that addresses this:

import json
import bluetooth
import threading
import time

# Use a thread-safe flag to control the lap thread
lap_active = threading.Event()
lap_thread = None

def start_laps(data):
    lap_active.set()  # Mark lap as running
    while lap_active.is_set():
        # Your lap processing logic goes here (e.g., timing, logging)
        print(f"Processing lap with data: {data}")
        time.sleep(1)  # Prevent CPU spiking
    print("Lap thread stopped")

def main():
    global lap_thread
    # Set up Bluetooth server
    server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
    server_sock.bind(("", bluetooth.PORT_ANY))
    server_sock.listen(1)
    port = server_sock.getsockname()[1]
    service_uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
    bluetooth.advertise_service(server_sock, "PiLapTracker", service_id=service_uuid)
    
    print(f"Waiting for Bluetooth connection on port {port}")
    client_sock, client_info = server_sock.accept()
    print(f"Connected to {client_info}")

    try:
        # Keep listening for Bluetooth commands indefinitely
        while True:
            data = client_sock.recv(1024)
            if not data:
                break  # Connection closed
            
            # Parse incoming command
            cmd = json.loads(data.decode("utf-8"))
            if cmd["action"] == "start_lap":
                if not lap_active.is_set():
                    # Start the thread WITHOUT calling join()
                    lap_thread = threading.Thread(target=start_laps, args=(cmd["data"],))
                    lap_thread.daemon = True  # Auto-exit when main thread ends
                    lap_thread.start()
                    print("Lap tracking started")
            elif cmd["action"] == "stop_lap":
                lap_active.clear()  # Signal thread to stop
                if lap_thread:
                    lap_thread.join(timeout=2)  # Optional: Wait for clean shutdown
                    print("Lap tracking stopped")
    except IOError as e:
        print(f"Bluetooth error: {e}")
    finally:
        # Clean up resources
        lap_active.clear()
        if lap_thread:
            lap_thread.join(timeout=1)
        client_sock.close()
        server_sock.close()
        print("Connection closed")

if __name__ == "__main__":
    main()

2. Use threading.Event() instead of global variables

I swapped out a simple global flag for threading.Event() because it's designed for thread-safe communication—no race conditions to worry about when toggling the lap state.

3. Set threads as daemon threads

Adding lap_thread.daemon = True ensures that if your main thread exits (e.g., if the Bluetooth connection drops), the lap thread will automatically shut down instead of lingering in the background.

Quick Extra Tips

  • Handle Bluetooth instability: The Raspberry Pi's Bluetooth can be flaky, so wrapping your listen loop in a try/except block prevents crashes from unexpected disconnections.
  • Thread-safe resources: If start_laps accesses shared files or hardware (like a display), use threading.Lock() to prevent data corruption or hardware conflicts.

内容的提问来源于stack exchange,提问作者Sara Fuerst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:50:39