我有一个应用程序,它使用线程中的getline()从标准input中读取数据。 我想从主线程closures应用程序,而getline仍然阻塞另一个线程。 这怎么能实现?
我不想强迫用户不得不按Ctrl + Zclosures标准input和应用程序。
我已经在Windows 8.1 64bit,v120平台工具集上使用我的编译器设置(RuntimeLibrary = / MT)
freopen stdin,但它被内部locking阻塞
破坏线程,调用abort()
放回一个EOF,行结束到std :: cin,这也被阻塞了
*更新*
如何在operator new中使用unique_ptr
将basic_string <char16_t>传递给只接受wchar_t *和char *
在Unix上用现代C ++编写socket编程
Mac和Linux上C ++ 11asynchronous行为的区别
在linux / sys / class / gpio中写入文件时出错
detach()不起作用,exit()被一个锁阻塞
winapi TerminatThread()调用abort()
winapi CloseHandle(GetStdHandle(STD_INPUT_HANDLE))挂起
调用TerminateProcess() – 工作,但我想退出优雅
*更新2:解决scheme*
WriteConsoleInput()可以使std :: getline()从阻塞读取返回。 这适用于任何msvc运行库libray。 有关工作解决scheme的代码,请参阅接受的答案
#include <iostream> #include <thread> #include <string> #include <chrono> int main(int argc,char *argv[]) { bool stop = false; std::thread *t = new std::thread([&]{ std::string line; while (!stop && std::getline(std::cin,line,'n')) { std::cout << line; } }); std::this_thread::sleep_for(std::chrono::seconds(1)); stop = true; // how to stop thread or make getline to return here? return 0; }
C ++ / Linux:使用c ++ 11primefaces来避免在双映射mmap区域上进行部分读取
等待main()返回?
模板在不同命名空间中的专门化
在windows / cygwin中,steady_clock的分辨率只有10ms吗?
为什么只能安全地从信号处理程序调用asynchronous信号安全函数?
writeConsoleInput()可以使std :: getline从阻塞读取返回,所以即使在使用/ MT编译器选项时也可以解决问题。
#include <Windows.h> #include <iostream> #include <thread> #include <string> #include <chrono> #include <atomic> int main(int argc,char *argv[]) { std::atomic_bool stop; stop = false; std::thread t([&]{ std::string line; while (!stop.load() && std::getline(std::cin,'n')) { std::cout << line; } }); std::this_thread::sleep_for(std::chrono::seconds(1)); stop = true; DWORD dwTmp; INPUT_RECORD ir[2]; ir[0].EventType = KEY_EVENT; ir[0].Event.KeyEvent.bKeyDown = TRUE; ir[0].Event.KeyEvent.dwControlKeyState = 0; ir[0].Event.KeyEvent.uChar.UnicodeChar = VK_RETURN; ir[0].Event.KeyEvent.wRepeatCount = 1; ir[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN,MAPVK_VK_TO_VSC); ir[1] = ir[0]; ir[1].Event.KeyEvent.bKeyDown = FALSE; WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE),ir,2,&dwTmp); t.join(); return 0; }
没有标准甚至跨平台的解决方案来中断std:cin或std::thread 。 在这两种情况下,您都需要使用特定于操作系统的API。 你可以用std::thread::native_handle()来检索一个线程的特定于OS的句柄
作为一个快速和肮脏的黑客,你可以分离线程。 但要注意这 一点 。
int main(int argc,char *argv[]) { std::thread t([&] { std::string line; while (std::getline(std::cin,'n')) { std::cout << line; } }); t.detach(); std::this_thread::sleep_for(std::chrono::seconds(1)); }
也:
不需要在堆上分配线程:
std::thread t([]{ });
return 0; 在C ++中是不必要的
stop = true; 会触发编译错误,因为在此范围内没有声明stop
如果你打算以这种方式共享布尔标志,你将有一个典型的竞争条件 ,因此UB
对于非阻塞输入来说,可能最接近“标准”或“跨平台”的解决方案可能是ncurses(就像Windows上的* nix和pdcurses )
只要分离线程:
#include <iostream> #include <thread> #include <chrono> bool stop = false; int main(int argc,char *argv[]) { std::thread t([]{ bool stop = false; std::string line; while (!stop && std::getline(std::cin,'n')) { std::cout << line; } }); std::this_thread::sleep_for(std::chrono::seconds(1)); stop = true; // Without detach: g++: terminate called without an active exception t.detach(); return 0; }
更清洁的方式是
如果stdin得到用户输入,在线程中有一个正确的退出(不要终止交互式输入,
从stdin(这是系统相关的)的非阻塞读取
建立一个管道
使用套接字
如果没有别的办法,总是有核选择:
TerminateProcess(GetCurrentProcess(),0);
只要确保你已经刷新了你关心的任何运行时缓冲区。
这个代码是多线程的瑕疵。 首先,为什么要在堆上创建一个新的线程? 只需在堆栈中声明并调用std::thread::detach 。
第二,谁答应你stop在这方面的工作? 处理器缓存这个布尔值并且从不查看真实的布尔值(如果不是部分地优化它,或者其他编译技巧的话)。 你需要使它成为原子:
int main(int argc,'n')) { std::cout << line; } }); t.detach(); stop = true; }
在Windows 7上使用visual studio 2013进行编译,并按预期工作。
这适用于我,虽然它有点狡猾:
#include <Windows.h> #include <iostream> #include <thread> #include <string> #include <chrono> #include <atomic> int main(int argc,'n')) { std::cout << line; } }); std::this_thread::sleep_for(std::chrono::seconds(1)); stop = true; CloseHandle(GetStdHandle(STD_INPUT_HANDLE)); t.join(); return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。