我正在寻找一种方法,能够同时从网络接收数据时向终端输入数据。
为此,我创建了一个新的线程dataCapture
(std::thread
),它将使用std::cin
获取输入。主线是接收器。
当网络发送字符串“end”时,程序需要退出。
这是简化的代码:
void dataCapture()
while (! quit) {
std::string data;
std::cout << "Enter data: ";
std::cin >> data;
}
}
bool quit=false;
int main() {
// socket creation
// connection to server
const std::string quit_value = "end";
std::thread datacapture_T(dataCapture);
while (! quit) {
char recep[1024];
recv(sd, recep, sizeof(recep),0);
if (recep == quit_value) {
quit=true;
}
}
datacapture_T.join();
return 0;
}
这不起作用,因为在接收"end"
后,main
在datacapture_T.join()
阻挡,因为dataCapture
在std::cin
电话中受阻。
是否有可能从主要解锁dataCapture
线程?
如果不是可以强行杀死它?
ps:我没有为了简化而包含锁。
感谢帮助!
你可以用std::cin
关闭ctrl-z
。
解决这个问题的另一种方法是进入你的dataCapture()
并通过做一个quit_value
检查那里的break
。
编辑:考虑使用原子以及尽可能明确地定义读取/写入并发线程。不要认为它增加了太多的复杂性
在理论上和实践中都没有以编程方式杀死线程的干净方法。
以编程方式解除阻塞和关闭线程的标准方法是等待输入(任何类型)是使用select()
和pipe()
:
select()
which创建一个包含输入文件描述符和read()
以及pipe()
的文件描述符集。cin
上进行阻塞读取,而是对select()
进行阻止调用。select()
告诉你有什么东西可以从pipe()
读取,退出线程。您可以清除所有资源并完成所有处理,因为您在线程中检测到终止请求。这是关键。select()
告诉你有什么东西要从cin读取,请阅读并处理它。pipe()
中写一个字节(值无关紧要)。
join()
线程。您认为这种方法听起来是随意而复杂的?它是!然而,这是常见的做法,您可以依赖它来工作,因为它被许多框架和程序使用。
还有一些不太有利的选择,例如轮询输入(非阻塞)和检查停止标志。也许最有用的替代方法是根本不使用任何其他线程来获取输入,并对所有I / O使用单线程事件驱动系统,并在其他线程中执行内部处理。
线程不是实现I / O并发的有用机制。线程对于创建CPU处理并发很有用。