为什么以下程序在 WSL2 中 printf“线程 1 存在”两次?

问题描述 投票:0回答:1

我目前正在 WSL2 上使用 C++ 多线程,但遇到了一些困难。运行我的程序时,我从单个线程收到重复的 printf 输出。以下是我正在运行的程序:

#include <atomic>
#include <condition_variable>
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <iostream>
#include <future>

std::atomic<int> g_Flag = 0;
std::atomic<int> cnt = 0;

void worker1(std::future<int> fut) {
    printf("this is thread 1\n");
    g_Flag = 1;
    cnt++;
    fut.get();
    printf("thread 1 exists\n");
}

void worker2(std::promise<int> prom) {
    printf("this is thread 2\n");
    g_Flag = 2;
    cnt++;
    prom.set_value(10);
    printf("thread 2 exists\n");
}

 
using namespace std::chrono_literals;
int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    std::thread t1(worker1, std::move(fut));
    std::thread t2(worker2, std::move(prom));
    while (cnt.load() != 2) {

    }
    t1.detach();
    t2.detach();
    printf("main exists\n");
    return 0;
}

程序输出:

eugene@DESKTOP-P8P395D:~/tron$ ./a.out 
this is thread 1
this is thread 2
main exists
thread 2 exists
thread 1 exists
thread 1 exists

如您所见,它打印了两次“线程 1 存在”。 关于为什么会发生这种情况有什么见解吗?我相信这可能与 WSL2 环境有关,因为在正常情况下,我只希望每个线程打印一次退出消息。任何帮助或指导表示赞赏。谢谢!

c++ concurrency windows-subsystem-for-linux
1个回答
0
投票

您应该首先排列代码:

#include <atomic>
#include <thread>
#include <iostream>
#include <future>
#include <syncstream>

std::atomic<int> g_cnt = 0;


void log(const char* str)
{
     std::osyncstream ss(std::cout);
     ss << str << std::endl;
}


void worker1(std::future<int> fut) 
{
    log("this is thread 1");
    g_cnt++;
    fut.get();
    log("thread 1 exists");
}


void worker2(std::promise<int> prom) 
{
    log("this is thread 2");
    g_cnt++;
    prom.set_value(10);
    log("thread 2 exists");
}


int main()
{
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();

    // Fire the 2 threads:
    std::thread t1(worker1, std::move(fut));
    std::thread t2(worker2, std::move(prom));

    t1.join();
    t2.join();

    log("main exists");
}

我修复了你的代码:

  • 稀释了 #include 行以仅包含必要的内容。
  • 将 main() 中的 while 循环和 detach() 替换为 join(),以确保主线程等待所有子线程完成后再退出。
  • 删除了未使用的 g_Flag 变量。
  • 删除了未使用的“using namespace”指令以实现更好的实践。

  • 此外,我将用syncstream 替换 printf 调用。

--

打印正确:演示

© www.soinside.com 2019 - 2024. All rights reserved.