gpt4 book ai didi

c++ - printf 调用搞砸了 std::thread 但 std::cout 很好

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:12:22 31 4
gpt4 key购买 nike

当使用 printf (stdio.h) 时,“启动两个线程\n”和“输入数字\n”混合在一起(类似“StEanterrt b a oth thnureaber\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;
}

最佳答案

std::cout 也不保证交错; C++03 中没有提到它,C++11 的 FDIS 在§27.4.1 [iostream.objects.overview] 中说了以下内容:

Concurrent access to a synchronized (§27.5.3.4) standard iostream object’s formatted and unformatted input (§27.7.2.1) and output (§27.7.3.1) functions or a standard C stream by multiple threads shall not result in a data race (§1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]

末尾的注释基本上意味着“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 函数的使用;只要始终如一地完成,就可以保证不会出现交错。

关于c++ - printf 调用搞砸了 std::thread 但 std::cout 很好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39092042/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com