Can anyone point me at the thing I try to do in this code, because SecondLoop thread is unreachable at all? It becomes reachable only if I remove while(true) loop.
#include <iostream>
#include <thread>
using namespace std;
void Loop() {
while(true) {
(do something)
}
}
void SecondLoop() {
while(true) {
(do something)
}
}
int main() {
thread t1(Loop);
t1.join();
thread t2(SecondLoop);
t2.join(); // THIS THREAD IS UNREACHABLE AT ALL!
return false;
}
The reason why I use multithreading is because I need to get two loops running at the same time.
join blocks the current thread to wait for another thread to finish. Since your t1 never finishes, your main thread waits for it indefinitely.
Edit:
To run two threads indefinitely and concurrency, first create the threads, and then wait for both:
int main() {
thread t1(Loop);
thread t2(SecondLoop);
t1.join();
t2.join();
}
To run Loop and SecondLoop concurrency, you have to do something like:
#include <iostream>
#include <thread>
void Loop() {
while(true) {
//(do something)
}
}
void SecondLoop() {
while(true) {
//(do something)
}
}
int main() {
std::thread t1(Loop);
std::thread t2(SecondLoop);
t1.join();
t2.join();
}
as join block current thread to wait the other thread finishes.
.join() waits for the thread to end (so in this case if you break out of the while loops and exit the thread function)
using while(true) is linked to the tread running , you should look for a way to exit that loop, use some sort of loop control
Based on my comment and what #Nidhoegger answered I suggest:
int main() {
thread t1(Loop);
thread t2(SecondLoop);
// Your 2 threads will run now in paralel
// ... <- So some other things with your application
// Now you want to close the app, perhaps all work is done or the user asked it to quit
// Notify threads to stop
t1running = false;
t2running = false;
// Wait for all threads to stop
t1.join();
t2.join();
// Exit program
return false;
}
Related
I need a thread to perform processing every one second accurately. Suppose if the worker thread is busy on some operation that takes more than one second, I want the worker thread to miss the 1s expiry notification and perform the processing in the next cycle.
I am trying to implement this using two threads. One thread is a worker thread, another thread sleeps for one second and notifies the worker thread via condition variable.
Code is shown below
Worker thread
while(!threadExit){
std::unique_lock<std::mutex> lock(mutex);
// Block until a signal is received
condVar_.wait(lock, [this](){return (threadExit || performProc);)});
if(threadExit_){
break;
}
// Perform the processing
..............
}
Timer thread
while(!threadExit)
{
{
std::unique_lock<std::mutex> lock(mutex);
performProc= false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if(threadExit){
break;
}
{
std::unique_lock<std::mutex> lock(mutex);
performProc= true;
}
condVar.notify_one();
}
Please note the variable threadExit is set by the main thread under the mutex lock and notified to worker thread. The timer thread can see this flag when it wakes up(which should be fine for my implementation)
Do you think performProc may set to false again before the worker thread sees it as true? If yes, can you please throw some light on how to tackle this problem? Thanks!
Unless threadExit is atomic, the code exhibits undefined behavior (race condition). All accesses to threadExit must be protected by a mutex, so also reads in while(!threadExit) and if(threadExit)....
But there's no need to do any of this. You can run everything in the same thread if you use sleep_until (and a steady clock) instead of sleep_for.
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::literals;
void do_work() {
std::cout << "Work # " << std::chrono::system_clock::now() << std::endl;
}
int main() {
while (true) {
auto t = ceil<std::chrono::seconds>(std::chrono::steady_clock::now() + 600ms);
std::this_thread::sleep_until(t);
do_work();
}
}
Output:
Work # 2022-03-04 09:56:51.0148904
Work # 2022-03-04 09:56:52.0134687
Work # 2022-03-04 09:56:53.0198704
Work # 2022-03-04 09:56:54.0010437
Work # 2022-03-04 09:56:55.0148975
. . .
I created one thread in my main program, thread execution has to stop once the main program will terminate. I am using reader.join(); to terminate the thread execution. But it is not stopping the execution.
I tried with below-mentioned code, I am using thread.join(); function, but it is failed to terminate a thread. And after the main program also my thread is kept executing.
#include <algorithm>
#include <array>
#include <atomic>
#include <mutex>
#include <queue>
#include <cstdint>
#include <thread>
#include <vector>
using namespace std;
using namespace std::chrono;
typedef pair<int, Mat> pairImage;
class PairComp {
public:
bool operator()(const pairImage& n1, const pairImage& n2) const
{
if (n1.first == n2.first)
return n1.first > n2.first;
return n1.first > n2.first;
}
};
int main(int argc, char* argv[])
{
mutex mtxQueueInput;
queue<pairImage> queueInput;
int total = 0;
atomic<bool> bReading(true);
thread reader([&]() {
int idxInputImage = 0;
while (true) {
Mat img = imread("img_folder/");
mtxQueueInput.lock();
queueInput.push(make_pair(idxInputImage++, img));
if (queueInput.size() >= 100) {
mtxQueueInput.unlock();
cout << "[Warning]input queue size is " << queueInput.size();
// Sleep for a moment
sleep(2);
}
else {
mtxQueueInput.unlock();
}
}
bReading.store(false);
});
while (true) {
pair<int, Mat> pairIndexImage;
mtxQueueInput.lock();
if (queueInput.empty()) {
mtxQueueInput.unlock();
if (bReading.load())
continue;
else
break;
}
else {
// Get an image from input queue
pairIndexImage = queueInput.front();
queueInput.pop();
}
mtxQueueInput.unlock();
cv::Mat frame = pairIndexImage.second;
cv::rectangle(frame, cv::Rect{ 100, 100, 100, 100 }, 0xff);
}
cv::imshow("out_image", frame);
waitKey(1);
if (total++ == 200)
break;
if (reader.joinable()) {
reader.join();
}
return 0;
}
thread.join() does not cause the thread to terminate, it waits until the thread ends. It's the responsibility of the thread to end its execution, for example by periodically checking for a certain condition, like a flag.
You already have an atomic flag bReading, which appears to cause the thread to exit.
if (queueInput.empty()) {
mtxQueueInput.unlock();
if (bReading.load())
continue;
else
break; // thread will exit when queue is empty and bReading == false
So all you need is to set bReading = false in the outer thread before calling thread.join().
bReading = false;
reader.join();
Note that bReading.store(false); inside your thread will have no effect.
Note: you don't need to call atomic.load() and atomic.store(), you can just use them in your code, which will call load() and store() implicitly.
I'm not aware of an built in possibility to stop a thread. Since you have a endless-loop embedded in your thread, it won't stop at any time.
std::thread::join does not terminate your thread. You have to implement something to end your loop, when you demand it.
A bool variable you set false when the thread has to exit. e.g. while(run) or something like that; for simplicity you could also use a std::atomic<bool>
A signaling variable you check. std::condition_variable
What you do at the moment is, you wait in your main-thread that your thread terminates. Since std::thread::join does't terminate your thread, your main-thread will execute forever.
NOTE: When you choose to implement the bool solution. You should protect this bool with an mutex or something alike.
Thanks for the comment. As I don't want to point everyone to boost, but you mentioned it. Find information here.
The problem is not with join which (btw) is not meant to be used to stop or terminate a thread.
The function that your thread is executing contains a while(true) which will never terminate, because it can only sleep and unlock the lock, nothing else.
This means that bReading.store will never be called and as a consequence in the main thread loop you will always go though this branch of the is
if (bReading.load())
continue;
meaning that also the main will execute forever.
std::join is used to wait from a thread that another thread has completed its work. when you do thread1.join() from the main thread what happens is that main will wait until thread1 has completed its execution before executing any other instruction.
I try to make a timeout in a C++ program:
...
void ActThreadRun(TimeOut *tRun)
{
tRun->startRun();
}
...
void otherFunction()
{
TimeOut *tRun = new TimeOut();
std::thread t1 (ActThreadRun, tRun);
t1.join();
while(tRun->isTimeoutRUN())
{
manageCycles();
}
}
...
The timeout is done after 3 seconds, and tRun->isTimeoutRUN() changes its state.
But if I "join" the thread, I block the program, so it waits 3 seconds before continuing, so it never goes into my while loop...
But if I don't "join" the thread, the thread never times out, and tRun->isTimeoutRUN() never changes, so it runs infinitely.
I'm not good with threads, so I'm asking your help because I don't understand the tutorials on this in C++.
You can use the new C++11 facilities
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
void sleep()
{
std::chrono::milliseconds dura( 2000 );
std::this_thread::sleep_for( dura );//this makes this thread sleep for 2s
}
int main()
{
std::thread timer(sleep);// launches the timer
int a=2;//this dummy instruction can be executed even if the timer thread did not finish
timer.join(); // wait unil timer finishes, ie until the sleep function is done
std::cout<<"Time expired!";
return 0;
}
Hope that helps
I'm trying to implement a basic timer with the classic methods: start() and stop(). I'm using c++11 with std::thread and std::chrono.
Start method. Creates a new thread that is asleep for a given interval time, then execute a given std::function. This process is repeated while a 'running' flag is true.
Stop method. Just sets the 'running' flag to false.
I created and started a Timer object that show "Hello!" every second, then with other thread I try to stop the timer but I can't. The Timer never stops.
I think the problem is with th.join()[*] that stops execution until the thread has finished, but when I remove th.join() line obviously the program finishes before the timer start to count.
So, my question is how to run a thread without stop other threads?
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
class Timer
{
thread th;
bool running = false;
public:
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval,
const Timeout &timeout)
{
running = true;
th = thread([=]()
{
while (running == true) {
this_thread::sleep_for(interval);
timeout();
}
});
// [*]
th.join();
}
void stop()
{
running = false;
}
};
int main(void)
{
Timer tHello;
tHello.start(chrono::milliseconds(1000),
[]()
{
cout << "Hello!" << endl;
});
thread th([&]()
{
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
});
th.join();
return 0;
}
Output:
Hello!
Hello!
...
...
...
Hello!
In Timer::start, you create a new thread in th and then immediately join it with th.join(). Effectively, start won't return until that spawned thread exits. Of course, it won't ever exit because nothing will set running to false until after start returns...
Don't join a thread until you intend to wait for it to finish. In this case, in stop after setting running = false is probably the correct place.
Also - although it's not incorrect - there's no need to make another thread in main to call this_thread::sleep_for. You can simply do so with the main thread:
int main()
{
Timer tHello;
tHello.start(chrono::milliseconds(1000), []{
cout << "Hello!" << endl;
});
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
}
Instead of placing the join in start place it after running = false in stop. Then the stop method will effectively wait until the thread is completed before returning.
#include <thread>
#include <chrono>
using namespace std:
void f()
{
// Sleeping for a very long while
while (SOCKET s = accept(listening_socket, ...))
{
// ...
}
}
int main()
{
std::thread t(f);
DoSomething();
t.???(); /* What to place here to wake/terminate thread f? */
}
Under Win32, I can use TerminateThread() to kill a thread. But what I want is a cross-platform method to do that.
How should I do that gracefully in C++?
I would recommend sleeping on a broadcast signal, semaphore, condition variable, or something instead of doing a blocking sleep. Then your application just sets the signal and anyone that is sleeping will wake up and can exit. It is a much cleaner solution since it gives the thread body a chance to cleanup whatever it might be doing - including releasing locks!
Response to Update
In this specific case, call select with a timeout before you call accept.
The first issue comes from blocking mode socket accept, you should use non-blocking socket mode.
You can set a flag in while loop, for example:
struct AcceptHandler
{
AcceptHandler()
: is_terminated(false)
{
}
void accept()
{
while(!is_terminated)
{
// select
// accept
cout << " in loop " << endl;
}
}
void terminate()
{
is_terminated = true;
}
private:
std::atomic<bool> is_terminated;
};
int main()
{
AcceptHandler ah;
std::thread t(std::bind(&AcceptHandler::accept, std::ref(ah)));
t.join(); /// this is just demo, it blocks here
ah.terminate();
return 0;
}
I used a flag(is_terminated) in the sample you could use condition variable(preferred way).