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

树莓派Pico W使用_thread库实现数据采集与Web服务器并行运行的问题

树莓派Pico W使用_thread库实现数据采集与Web服务器并行运行的问题

嘿,我来帮你排查这个问题~你的思路完全没问题,用线程分离Web服务和数据采集逻辑是正确的,但看起来是几个细节没处理好导致Web服务器“失联”了:

问题根源分析

  1. 未读取客户端请求数据:当浏览器向服务器发起HTTP请求时,会先发送请求头信息,如果你的服务器不读取这些数据,TCP连接会卡在半开状态,后续的响应无法正常发送,浏览器就会一直显示“无法访问”。
  2. 缺少标准HTTP响应头:直接发送HTML内容而不附带HTTP状态码和响应头,部分浏览器无法正确解析响应,也会导致服务异常。
  3. Socket选项未配置:如果socket没有设置SO_REUSEADDR,可能会出现地址占用的问题,导致线程里的服务无法正常监听。

修改后的代码示例

首先修正serve函数:

def serve(connection):
    while True:
        client = connection.accept()[0]
        try:
            # 必须先读取客户端的请求数据,避免连接阻塞
            request = client.recv(1024)
            # 生成网页内容
            html = webpage()
            # 发送标准HTTP响应头
            client.send('HTTP/1.1 200 OK\n')
            client.send('Content-Type: text/html\n')
            client.send('Connection: close\n\n')
            # 发送网页内容
            client.send(html)
        except Exception as e:
            print(f"Error serving client: {e}")
        finally:
            # 确保客户端连接被关闭
            client.close()

然后检查open_socket函数,确保添加地址复用选项:

def open_socket(ip):
    import socket
    address = (ip, 80)
    connection = socket.socket()
    # 允许地址复用,避免重启时出现地址占用错误
    connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    connection.bind(address)
    connection.listen(1)
    print(f"Listening on {ip}:80")
    return connection

主线程逻辑保持不变即可:

ip = connect()
connection = open_socket(ip)
_thread.start_new_thread(serve, (connection,))

while True:
    GetSensorsValues()
    sleep(5)

额外说明

  • MicroPython的_thread库是抢占式调度的,主线程的sleep(5)会自动释放CPU资源给Web服务线程,不用担心阻塞问题。
  • 如果你需要在网页中展示实时采集到的传感器数据,可以把传感器值存在一个全局变量里,webpage()函数生成HTML时直接读取这个变量即可;如果涉及多线程修改全局变量,最好用_thread.allocate_lock()加个锁,避免数据混乱。

备注:内容来源于stack exchange,提问作者Romain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 03:19:30