scanf(), std::cin 在多线程环境中的行为如何
How do scanf(), std::cin behave on multithreaded environment?
我想用一个例子来说明我的问题。
假设有一个设置为运行此函数的 N /*(N>>1)*/
线程数组:
void Process() {
//Some thread safe processing which requires in-deterministic computation time
unsigned char byte;
std::cin >> byte;
}
一旦它们同时启动,会发生什么?如何处理并发 std::cin 访问?在控制台上操作的最终用户看到/体验到什么?
编辑:我还想补充一件事。下面的代码是否足够安全,可以放弃仅在一个(可能是主)线程中使用 std:cin 的想法?
void Process() {
//Some thread safe processing which requires in-deterministic computation time
//Mutex lock
unsigned char byte;
std::cin >> byte;
//Mutex unlock
}
说,如果没有互斥体,结果是不可预测的。
如果使用互斥锁,一切都很好。这就是互斥锁的用途。
在 C++11 之前,这取决于实现;至少一个实现保证了调用的同步。 (VC++保证std::cout
的同步,但不能保证其他IO流对象。 G++ 提供与 C++11 相同的保证,即使在早期版本的编译器中也是如此。在C++11中,它是显式未定义的行为。
一般规则很简单:对状态的任何修改任何线程中的对象都需要同步所有访问。并且std::istream
上的所有>>
运算符都被视为修改其状态。
更一般地说,对于任何特定的流,它可能是一个很好的仅在一个线程中使用它的策略。 (也有例外,例如日志记录流,其中日志记录对象确保线程安全。 对于输入尤其如此,因为即使外部同步,操作者的顺序将如果它们位于单独的线程中,则通常未指定。 所以即使使用同步,如果您的用户输入 "ab"
,线程得到'a'
,在你的例子中得到'b'
将是待定。
编辑:
标准流对象似乎有特殊规则(std::cin
、std::cout
等)。 并发访问是保证不会产生数据竞争,至少在某些情况下是这样。它仍然可能导致字符混合,即:如果你是输入int
(而不是单个字符)和您的用户输入 "123 89n"
,线程 1 可能会看到 "1389n"
和线程 2 "2 "
,这不会给你连贯结果。
我的全球建议成立。 我想不出任何现实的字符交错不会创建的情况一个问题。 (另外,我认为我从来没有写过这样的代码实际来自std::cin
的输入;它总是来自 std::istream&
可能是std::cin
的,也可能是一个文件。
第一个线程使用 std::cin 锁定它(除非您use sync_with_stdio(false)
)。因此,您不需要互斥锁。http://en.cppreference.com/w/cpp/io/cin无论如何,我不建议在多线程应用程序中使用它。问题是没有办法中断来自其他线程的 cin 输入。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::ifstream 在二进制模式下,语言环境在 C++ 中
- 在多线程环境中使用 std::call_once() 初始化
- std::wstring中ASCII符号的字节表示,具有不同的语言环境
- 语言环境"en_US"中 std::time_get::get_time() 的正确时间格式是什么?
- std::strtoull在我的JNI NDK环境下无法识别
- 在多线程环境中使用 std::string 时 Clang 的线程清理器警告
- scanf(), std::cin 在多线程环境中的行为如何
- Do std容器总是在多线程环境中抛出异常
- std:: lower的行为在不同的语言环境中是如何变化的?
- std::get_time和其他语言环境功能在Windows上无法正常工作
- C++11 std::vector在并发环境中的应用
- 环境变量在一个char*中,说明如何将其转换为std::字符串
- 读取和Huffman压缩4字节二进制字符串STD C++Linux环境