当使用printf(stdio.h)时,"启动两个线程\ n"和"输入一个数字\ n"混合在一起(类似于" StEanterrt b oththureaber \ nads \ n"),但这不会发生在std :: cout(iostream)中。我怀疑这与std :: thread有关,但我仍然是多线程编程的新手。
我真的不想使用iostream,因为它会让程序变得超大!
我正在使用mingw32 g ++ 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;
}
答案 0 :(得分:1)
std::cout
也不保证交错;在C ++ 03中没有提到它,而C ++ 11的FDIS在§27.4.1[iostream.objects.overview]中说明了以下内容:
同步访问同步(§27.5.3.4)标准iostream对象的格式化和未格式化输入(§27.7.2.1)和输出(§27.7.3.1)函数或多个线程的标准C流不得产生数据种族(§1.10)。 [注意:如果用户希望避免交错字符,则仍必须通过多个线程同步这些对象和流的并发使用。 - 结束说明]
最后的说明基本上意味着“std::cout
也允许交错字符”。由于编译器/运行时库特定的实现,或者由于尝试to synchronize itself with stdio.h
(关闭sync_with_stdio
可能导致它再次开始交错),它可能不会这样做。但它不是语言保证;你只是幸运。
如果希望输出不交错,则需要从单个线程执行所有I / O(让工作者接受参数和计算值,主线程负责执行I / O以输出计算结果)值),或显式锁定从目标相同流/ FILE*
的不同线程使用的所有I / O函数。您可以轻松使用stdio.h
,只需要使用std::mutex
来锁定std::lock_guard
(例如stdio.h
}围绕position: fixed;
height: 100%;
函数的使用;只要它始终如一地完成,就可以保证不会交错。