C++ 从另一个线程取消阻止一个线程
我正在寻找一种方法,能够在从网络接收数据的同时向终端输入数据 为此,我创建了一个新线程C++ 从另一个线程取消阻止一个线程,c++,multithreading,pthreads,C++,Multithreading,Pthreads,我正在寻找一种方法,能够在从网络接收数据的同时向终端输入数据 为此,我创建了一个新线程dataCapture(std::thread),它将使用std::cin获取输入。主线程是接收器 当网络发送字符串“end”时,程序需要退出 以下是简化代码: void dataCapture() while (! quit) { std::string data; std::cout << "Enter data: "; std::cin
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;
}
void dataCapture()
而(!退出){
std::字符串数据;
std::cout>数据;
}
}
bool-quit=false;
int main(){
//套接字创建
//与服务器的连接
const std::string quit_value=“end”;
线程数据捕获(datacapture);
而(!退出){
char-recep[1024];
recv(标准偏差,recep,尺寸(recep),0);
if(recep==退出值){
退出=真;
}
}
datacapture_T.join();
返回0;
}
这不起作用,因为在接收到“end”
后,main
阻塞了datacapture\u t.join()
,因为datacapture
在std::cin
调用中被阻塞
是否可以从main中取消阻止数据捕获
线程
如果没有,是否有可能强行杀死它
注:为了简化,我没有包括锁
谢谢你的帮助 您可以使用
ctrl-z
关闭std::cin
另一种解决方法是进入dataCapture()
并通过执行break
检查quit\u值
<>编辑:考虑使用原子,以尽可能好地保持对并发线程的读/写。不要认为它增加了太多的复杂性无论在理论上还是在实践中,都没有干净的方法可以通过编程杀死线程
以编程方式取消阻止和关闭等待输入(任何类型)的线程的标准方法是使用select()
和pipe()
:
- 创建管道()
- 为
select()
创建一个文件描述符集,其中包含您的输入文件描述符、read()
和pipe()
- 不要在
cin
上执行阻塞读取,而是对select()
执行阻塞调用
- 如果
select()
告诉您要从管道()读取某些内容,请退出线程。您可以清理所有资源并完成所有处理,因为您正在线程中检测终止请求。这是关键
- 如果
select()
告诉您需要从cin读取某些内容,请读取并处理它
- 从任何其他螺纹,例如在main()的末端:
- 每当您想要终止线程时,将一个字节(值无关紧要)写入
管道()
join()
线程
你觉得这个方法听起来很武断和复杂吗?它是!然而,这是一种常见的做法,您可以依靠它来工作,因为许多框架和程序都使用它
还有一些不太好的选择,比如轮询输入(非阻塞)和检查停止标志。也许最有用的替代方法是根本不使用任何其他线程来获取输入,对所有I/O使用单线程事件驱动系统,只在其他线程中进行内部处理
线程不是实现I/O并发的有用机制。线程对于创建CPU处理并发性非常有用。尝试关闭std::cin
您可以将quit作为引用传递给线程方法(必须在使用std::ref的线程中显式执行),然后在主线程中更改它时,它将使线程方法退出。@PaulSanders对不起,我该怎么做?你的意思是关闭stdin吗?如果是,该程序实际上会在加入后调用另一个使用std::cin
的函数,那么我能重新打开它吗?@RasmusDall我想我不理解你的想法抱歉。问题在于线程在std::cin
上被阻塞,而不是它无法检测到quit
changed valuecin
不是为此而构建的。为了获得最佳效果,您必须使用允许终止或超时的系统特定调用。一个例子:这非常有效,谢谢!我还尝试了一种方法,在(!quit)
循环时,select处于状态,并且每1秒超时一次,这种方法是:如果stdin上有输入,它将处理它,否则它将在检查后执行下一次迭代!退出
。这是不是表现不佳?调用无限制超时的select是否在内部具有while(true)
?@Jonas:select()
挂起线程并允许其他线程运行,直到有事情要做,因此这是最有效的方法,因为它允许其他线程进程在无事可做的情况下运行。在内部,它不使用轮询,而是直接使用内部操作系统事件。但是很多程序使用1s(大约)的超时作为最后手段,以防pipe()机制失败,实际上对于简单的程序,1s超时更好,因为实现它的代码要少得多,而且通常1s最坏情况下的终止延迟是可以接受的。