C++中如何将子线程的返回数据传递至主线程
非阻塞式子线程结果传递方案
1. 回调函数(最常用)
启动子线程时,把主线程的回调函数传进去,子线程处理完数据后直接调用该函数传递结果,主线程无需等待,子线程完成后自动触发结果处理。
示例(Python):
import threading def long_running_task(callback): # 模拟耗时操作 import time time.sleep(5) result = "子线程处理完成的数据" # 调用回调传递结果 callback(result) def handle_result(data): print(f"主线程收到结果:{data}") # 启动子线程并传入回调 threading.Thread(target=long_running_task, args=(handle_result,)).start() # 主线程继续执行其他操作 print("主线程继续执行其他操作...")
2. 线程安全消息队列(解耦性强)
用线程安全的队列存储结果,子线程处理完成后将数据放入队列,主线程可在空闲时非阻塞式读取,或单独开一个轻量线程监听队列,避免阻塞主线程核心逻辑。
示例(Python):
import threading import queue result_queue = queue.Queue() def long_running_task(): import time time.sleep(5) result = "子线程处理完成的数据" result_queue.put(result) # 启动子线程 threading.Thread(target=long_running_task).start() # 主线程继续执行其他操作 print("主线程继续执行其他操作...") # 开单独线程监听队列,不阻塞主线程 def listen_queue(): while True: try: data = result_queue.get_nowait() print(f"主线程收到结果:{data}") break except queue.Empty: # 无结果时短暂休眠,避免空轮询占用资源 import time time.sleep(0.5) threading.Thread(target=listen_queue).start()
3. 观察者模式(多场景适配)
定义观察者接口,主线程注册为观察者,子线程处理完成后通知所有注册的观察者,适合多个模块需要接收结果的场景。
示例(Java简化版):
import java.util.ArrayList; import java.util.List; // 观察者接口 interface ResultObserver { void onResultReceived(String result); } // 主线程作为观察者实现类 class MainObserver implements ResultObserver { @Override public void onResultReceived(String result) { System.out.println("主线程收到结果:" + result); } } // 子线程任务类 class LongTask implements Runnable { private List<ResultObserver> observers = new ArrayList<>(); public void addObserver(ResultObserver observer) { observers.add(observer); } @Override public void run() { try { Thread.sleep(5000); // 模拟耗时操作 String result = "子线程处理完成的数据"; // 通知所有观察者 for (ResultObserver observer : observers) { observer.onResultReceived(result); } } catch (InterruptedException e) { e.printStackTrace(); } } } // 主线程逻辑 public class Main { public static void main(String[] args) { LongTask task = new LongTask(); task.addObserver(new MainObserver()); new Thread(task).start(); // 主线程继续执行其他操作 System.out.println("主线程继续执行其他操作..."); } }
4. 语言原生异步API(最简洁)
多数语言都有原生异步机制,比如Python的asyncio、JavaScript的Promise、Java的CompletableFuture,这些API内置非阻塞结果传递逻辑,无需手动管理线程。
示例(JavaScript):
// 模拟耗时异步任务 function longRunningTask() { return new Promise((resolve) => { setTimeout(() => { resolve("子线程处理完成的数据"); }, 5000); }); } // 主线程通过then接收结果,不阻塞 longRunningTask().then((result) => { console.log("主线程收到结果:", result); }); // 主线程继续执行其他操作 console.log("主线程继续执行其他操作...");
避坑提醒
- 禁止使用
join()或阻塞式获取结果的方法,会导致主线程等待子线程完成。 - 跨线程共享数据时必须保证线程安全,优先用线程安全容器或加锁机制。
内容的提问来源于stack exchange,提问作者Selva Srithiban
相关产品推荐
相关产品推荐

