Python并行处理扫码输入与HTTP请求时多线程传参报错如何解决
报错原因
- 直接原因:
threading.Thread的args参数要求传入元组类型,你当前直接传入了空列表ids,空列表被解析为无参数集合,调用updateOrder时没有传入必填的ids参数,因此触发TypeError。 - 额外逻辑问题:
- 现有
updateOrder的循环仅在启动时校验一次ids长度,初始ids为空时线程会直接退出,后续新扫描的ID不会被处理 - 多线程同时读写同一个列表存在竞态条件,可能出现数据丢失、异常报错的问题
- 现有
修复实现
首先调整线程传参格式,修改updateOrder的循环逻辑,增加线程锁保证数据安全,完整代码如下:
import requests from requests.models import HTTPBasicAuth import threading import time # 存储扫描到的ID ids = [] # 线程锁,保证列表读写安全 lock = threading.Lock() # 从扫描器获取输入 def getInput(): while True: newId = str(input("BillBeeId eingeben")) with lock: ids.append(newId) # 标记订单为已打印 def updateOrder(ids): while True: current_id = None # 加锁读取列表,避免竞态 with lock: if len(ids) > 0: current_id = ids.pop(0) if current_id: response = requests.post( f'https://app.billbee.io/api/v1/orders/{current_id}/tags', auth=HTTPBasicAuth('xxx', 'xxx'), headers={'X-Billbee-Api-Key': 'xxx'}, json={ "Tags": [ "Lieferschein-Gedruckt" ] } ) print(response) else: # 无待处理ID时休眠0.1秒,避免CPU空转 time.sleep(0.1) t1 = threading.Thread(target=getInput, daemon=True) # args参数传入单元素元组,注意末尾的逗号 t2 = threading.Thread(target=updateOrder, args=(ids,), daemon=True) t1.start() t2.start() # 主线程保持运行 while True: time.sleep(1)
主要修改点:
- 线程传参改为
args=(ids,),符合threading.Thread的元组传参要求,解决参数缺失报错 - 将
updateOrder改为无限循环,持续监听待处理ID列表,不会因为初始为空就退出 - 增加线程锁保证列表读写的原子性,避免多线程操作异常
- 增加休眠逻辑避免无任务时CPU空转,设置线程为daemon线程方便程序退出
内容的提问来源于stack exchange,提问作者Jakob R.
相关产品推荐
相关产品推荐

