C++独立线程调用getline,线程间参数传递失败求助
解决多线程下getline非阻塞共享变量同步问题
问题根源
你代码里的std::ref用法是对的,问题出在多线程共享变量的内存可见性和竞态条件:
- 编译器可能对主线程的while循环做优化,将
commandString.empty()的读取缓存到寄存器,导致子线程修改了内存中的值,主线程却看不到。 - 子线程修改
std::string时,主线程可能同时读取,string的内部状态(比如指针、长度)可能处于不一致状态,触发未定义行为。
解决方案
方案1:用互斥锁保护共享变量
通过std::mutex确保对共享string的读写操作互斥,同时强制内存同步,让主线程能看到子线程的修改:
#include <iostream> #include <string> #include <thread> #include <mutex> std::mutex mtx; void getlineThread(std::string& commandString) { while (true) { std::string temp; std::getline(std::cin, temp); // 加锁修改共享变量 std::lock_guard<std::mutex> lock(mtx); commandString = temp; std::cout << "here : " << temp << std::endl; } } int main() { std::string commandString; std::thread thread(getlineThread, std::ref(commandString)); while (true) { std::string currentCommand; // 加锁读取共享变量 std::lock_guard<std::mutex> lock(mtx); currentCommand = commandString; if (!currentCommand.empty()) { std::cout << "Command: " << currentCommand << std::endl; break; } } thread.join(); }
方案2:用条件变量避免空循环(更高效)
如果不想让主线程一直空循环浪费CPU,可以用std::condition_variable,子线程更新变量后主动通知主线程:
#include <iostream> #include <string> #include <thread> #include <mutex> #include <condition_variable> std::mutex mtx; std::condition_variable cv; bool hasNewInput = false; void getlineThread(std::string& commandString) { while (true) { std::string temp; std::getline(std::cin, temp); std::lock_guard<std::mutex> lock(mtx); commandString = temp; hasNewInput = true; cv.notify_one(); // 通知主线程有新输入 std::cout << "here : " << temp << std::endl; } } int main() { std::string commandString; std::thread thread(getlineThread, std::ref(commandString)); std::unique_lock<std::mutex> lock(mtx); // 等待直到有新输入,自动处理锁的释放和重获取 cv.wait(lock, []{ return hasNewInput; }); std::cout << "Command: " << commandString << std::endl; thread.join(); }
补充说明
std::ref的作用是让std::thread传递引用而非复制参数,你的用法没问题,不是问题根源。- 多线程共享任何非原子类型的变量时,都必须用同步机制(互斥锁、条件变量等)保护,否则会出现未定义行为。
内容的提问来源于stack exchange,提问作者Alexandre Boucard
相关产品推荐
相关产品推荐

