Printf调用与std::thread混淆,但std::cout没有问题
printf calls messed up with std::thread but std::cout are fine
当使用printf (stdio.h)时,"启动两个线程n"answers"输入一个数字n"混合在一起(类似于" steantert b a th thnureabernadsn"),但在std::cout (iostream)中不会发生这种情况。我怀疑这与std::thread有关,但我仍然是多线程编程的新手。
我真的不想使用iostream,因为它使程序超大!
我使用的是mingw32g++ 4.9.2,用g++ -o foreback foreback.cpp -O2 -std=c++11
编译。(虽然我的电脑是64位的,但是我发现mingw-w64产生的程序大约是mingw32的两倍大,所以我没有使用它)
//#define IOS
#ifdef IOS
#include <iostream>
#endif
#include <stdio.h>
#include <thread>
#include <atomic>
#include <windows.h> // for Sleep()
std::atomic<int> atom(1);
void foreground() {
int c = 1;
while (c) {
#ifdef IOS
std::cout << "Enter a number: ";
std::cin >> c;
#else
printf("Enter a number: ");
scanf("%d", &c);
#endif
atom.store(c, std::memory_order_relaxed);
}
}
void background() {
FILE *out = fopen("foreback.txt", "w");
int c = 1;
while (c) {
fprintf(out, "%d", c);
c = atom.load(std::memory_order_relaxed);
Sleep(500);
}
fclose(out);
}
int main() {
std::thread f(foreground), b(background);
#ifdef IOS
std::cout << "Start both threads.n";
#else
printf("Start both threads.n");
#endif
f.join();
b.join();
#ifdef IOS
std::cout << "End of both threads.n";
#else
printf("End of both threads.n");
#endif
return 0;
}
std::cout
也不保证交错;c++ 03中没有提到它,c++ 11的FDIS在§27.4.1 [iostream.objects.overview]中说了以下内容:
通过多个线程并发访问synchronized(§27.5.3.4)标准iostream对象的格式化和未格式化的输入(§27.7.2.1)和输出(§27.7.3.1)函数或标准C流不会导致数据竞争(§1.10)。[注:如果用户希望避免交叉字符,他们仍然必须同步多线程对这些对象和流的并发使用。]
最后的注释基本上意味着"std::cout
也允许交错字符"。通常,由于编译器/运行时库特定的实现,或者由于试图与stdio.h
同步(关闭sync_with_stdio
可能会导致它再次开始交错),它可能不会这样做。但这并不是语言的保证;你真走运。
如果你想输出不交错,你需要从一个线程执行所有的I/O(让你的工人接受参数和计算值,主线程负责执行I/O来输出计算值),或者显式地锁定来自不同线程的所有I/O函数,目标是相同的流/FILE*
。你可以很容易地使用stdio.h
,你只需要有一个std::mutex
,你锁定(例如与std::lock_guard
)围绕你使用stdio.h
函数;
- std::cout.imbue()多重调用
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 为什么在C的循环中使用printf的Rust代码不显示输出,而在C++的循环中显示std::cout
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- std::cout输出int时出现编译错误
- 为什么 std::cout 打印浮点数、双精度和长双精度到相同的小数精度?
- main() 中的 std::cout 在调试期间不会在调试控制台中打印任何内容
- std::cout 来自多个线程
- 在 c++ 中以十六进制格式打印无符号字符(BYTE).使用 std::cout
- Cuda 基本程序 (将值写入矩阵和 std:cout 不起作用) ;主功能不启动
- 是否可以为 std::cout 创建别名?
- std::cout 在打印变量与函数表达式时的行为不同
- 带有 std::cout 的多线程控制台文本动画
- 捕获/禁止发送到 std::cout 的 OpenCV 警告
- printf() 和 std::cout 在指针方面的区别
- 使用字符串流加速 std::cout 日志记录
- 是否可以在每次使用std::cout时执行一个函数
- 为什么'std::cout << !+2 '输出 0?
- 如何将自定义类传递给std::cout
- 对于输出,std::copy是否比std::cout快