I am currently working with C++ multithreading on WSL2 and I've encountered something stumping. When running my program, I'm receiving duplicate printf output from a single thread. Below is the program that I'm running:
#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;
}
The program output:
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
As you can see, it prints "thread 1 exists" twice. Any insights on why this could be happening? I believe it may have to do with the WSL2 environment, as under normal circumstances, I would only expect each thread to print its exit message once. Any help or direction is appreciated. Thanks!
Your output:
Before I see that "it prints "thread 1 exists" twice.", I see that it prints after "main exists":
It's not recommended to use standard output (stdout) from a detached thread after the
main()function exits.It’s generally a good practice to ensure all threads have completed before allowing the
main()function to exit.(Mitigation) To ensure
main()exits only after workers has nothing to do / access nothing anymore,cntis incremented at the very end of worker function:--
The recommended approach involves restructuring the code:
Key points:
whileloop ("busy wait") anddetach()withjoin()in themain()to ensure that the main thread waits for all child threads to finish before exiting.#includelines to include only what's necessary - For better practice.using namespacedirective - For better practice.printf()calls withstd::osyncstream.Demo
Now, the output is:
--
UPDATE:
Due to your comment: "The detach used but not join here is the requirements from test. I cannot change that.". This solution works with
detach():Demo
Now, the output is: (The same)