Optimizing threading in C++ - c++

I have three issues with the attached code, which has to do with threading. I need to make function calls to provide information about the following three items:
Is the thread vecOfThreads[1] empty without any tasks currently running on it
Is the thread vecOfThreads[0] joinable() but not ready to be join()ed
This would be the else statement of 2). If a thread is joinable() and won't wait to join() then go ahead and join()
#include <iostream>
#include <chrono> // std::chrono::microseconds
#include <thread> // std::this_thread::sleep_for
#include <vector>
void f1();
void f1() {
std::this_thread::sleep_for(std::chrono::seconds {3});
std::cout << "DONE SLEEPING!" << std::endl;
}
int main() {
int processor_count = 2; // consider that this CPU has two processors
std::vector<std::thread> vecOfThreads(processor_count);
std::thread t1(f1);
vecOfThreads[0] = std::move(t1);
if (vecOfThreads[0].joinable()) { // how to check to see if vecOfThreads[1] would be good to start a process on?
std::cout << "this is joinable, but not yet ready to be joined \n";
std::cout << "How to know: \n \t 1) if the thread is not being used "
"\n \t 2) if the thread is in use, but not yet ready to be `join()`ed \n \t "
"3) if the thread is both joinable and will not wait for a join()" << std::endl;
vecOfThreads[0].join();
}
return 0;
}
Compile with
g++ -std=c++17 -pthread
I would like to be able to submit say 12 tasks, but I only have 2 threads available. I want for a new task to be submitted right away when one of the threads finish. Is this possible?
Thank you for your time.

Related

Call a function after x seconds while keep running rest of the program in C++

I have a program in which I want to call a function after x seconds or minutes while keep running rest of the program.
You should run new thread:
#include <string>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
// The function we want to execute on the new thread.
void task(int sleep)
{
std::this_thread::sleep_for (std::chrono::seconds(sleep));
cout << "print after " << sleep << " seconds" << endl;
}
int main()
{
// Constructs the new thread and runs it. Does not block execution.
thread t1(task, 5);
// Do other things...
// Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
t1.join();
}

C++ call a function every x seconds

I am trying to run run() function every 5 seconds without stopping while() loop (parallelly). How can I do that ? Thanks in advance
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void run()
{
this_thread::sleep_for(chrono::milliseconds(5000));
cout << "good morning" << endl;
}
int main()
{
thread t1(run);
t1.detach();
while(1)
{
cout << "hello" << endl;
this_thread::sleep_for(chrono::milliseconds(500));
}
return 0;
}
In your main function, it is important to understand what each thread is doing.
The main thread creates a std::thread called t1
The main thread continues and detaches the thread
The main thread executes your while loop in which it:
prints hello
sleeps for 0.5 seconds
The main thread returns 0, your program is finished.
Any time from point 1, thread t1 sleeps for 5 seconds and then prints good morning. This happens only once! Also, as pointed out by #Fareanor, std::cout is not thread-safe, so accessing it with the main thread and thread t1 may result in a data race.
When the main thread reaches point 4 (it actually never does because your while loop is infinite), your thread t1 might have finished it's task or not. Imagine the potential problems that could occur. In most of the cases, you'll want to use std::thread::join().
To solve your problem, there are several alternatives. In the following, we will assume that the execution of the function run without the std::this_thread::sleep_for is insignificant compared to 5 seconds, as per the comment of #Landstalker. The execution time of run will then be 5 seconds plus some insignificant time.
As suggested in the comments, instead of executing the function run every 5 seconds, you could simply execute the body of run every 5 seconds by placing a while loop inside of that function:
void run()
{
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "good morning" << std::endl;
}
}
int main()
{
std::thread t(run);
t.join();
return 0;
}
If, for some reason, you really need to execute the run function every 5 seconds as stated in your question, you could launch a wrapper function or lambda which contains the while loop:
void run()
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "good morning" << std::endl;
}
int main()
{
auto exec_run = [](){ while (true) run(); };
std::thread t(exec_run);
t.join();
return 0;
}
As a side note, it's better to avoid using namespace std.
Just call your run function in seperate thread function like below. Is this ok for you?
void ThreadFunction()
{
while(true) {
run();
this_thread::sleep_for(chrono::milliseconds(5000));
}
}
void run()
{
cout << "good morning" << endl;
}
int main()
{
thread t1(ThreadFunction);
t1.detach();
while(1)
{
cout << "hello" << endl;
this_thread::sleep_for(chrono::milliseconds(500));
}
return 0;
}

boost signal and slot not working in different thread (using boost::asio::io_service)

I have written a small test program to understand the signal and slot mechanism provided by boost and their behavior when posted in different thread. I want to have slot's being called in different threads but the output of my program shows slots are not being called in different thread from which signal was emitted.
#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/random.hpp>
#include <boost/signals2.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/signals2/signal.hpp>
boost::signals2::signal<void (int)> randomNumberSig;
// ---------------- Thread 1 ----------------
boost::asio::io_service thread1_serv;
void handle_rnd_1(int number)
{
std::cout << "Thread1: " << boost::this_thread::get_id() << " & Number is " << number << std::endl;
}
void thread1_init(void)
{
std::cout << "Thread 1 Init" << std::endl;
boost::asio::io_service::work work (thread1_serv);
randomNumberSig.connect([] (int num) -> void {
std::cout << "Slot called from main thread" << std::endl;
thread1_serv.post(boost::bind(handle_rnd_1, num));
});
}
void thread1_loop(void)
{
}
void thread1(void)
{
thread1_init();
while (true) {
thread1_serv.run();
thread1_loop();
}
}
int main(int argc, char *argv[])
{
std::cout << "Starting the Program" << std::endl;
boost::thread t1(&thread1);
while (1) {
int num = 2;
std::cout << "Thread " << boost::this_thread::get_id() << " & Number: " << num << std::endl;
randomNumberSig(num);
boost::this_thread::sleep_for(boost::chrono::seconds(num));
}
return 0;
}
The output of the program is:
Starting the Program
Thread 7fae3a2ba3c0 & Number: 2
Thread 1 Init
Thread 7fae3a2ba3c0 & Number: 2
Slot called from main thread
Thread 7fae3a2ba3c0 & Number: 2
Slot called from main thread
Thread 7fae3a2ba3c0 & Number: 2
Slot called from main thread
I suspect post() method of the io_service is not working properly or I have missed something in initializing the io_service.
You don't handle invocation of run function properly.
You used work to prevent run from ending when there is no work to do.
But your work is local inside thread1_init so when this function ends, work
is destroyed and io_service::run exits when there are no handlers to be called.
After run finished, io_service is marked as stopped, and you need to call restart before
calling run (as subsequent invocation).
If you don't call restart, run returns immediately without processing any handlers - that is why you don't see them.
So first solution is to create work whose lifetime is the same as io_service (just use global variable - ugly):
boost::asio::io_service thread1_serv;
boost::asio::io_service::work work(thread1_serv);
Another solution, don't use work, just call restart before run:
thread1_init();
while (true) {
thread1_serv.restart();
thread1_serv.run();
thread1_loop();
}
Wandbox test

How to add a delay to code in C++.

I want to add a delay so that one line will run and then after a short delay the second one will run. I'm fairly new to C++ so I'm not sure how I would do this whatsoever. So ideally, in the code below it would print "Loading..." and wait at least 1-2 seconds and then print "Loading..." again. Currently it prints both instantaneously instead of waiting.
cout << "Loading..." << endl;
// The delay would be between these two lines.
cout << "Loading..." << endl;
in c++ 11 you can use this thread and crono to do it:
#include <chrono>
#include <thread>
...
using namespace std::chrono_literals;
...
std::this_thread::sleep_for(2s);
to simulate a 'work-in-progress report', you might consider:
// start thread to do some work
m_thread = std::thread( work, std::ref(*this));
// work-in-progress report
std::cout << "\n\n ... " << std::flush;
for (int i=0; i<10; ++i) // for 10 seconds
{
std::this_thread::sleep_for(1s); //
std::cout << (9-i) << '_' << std::flush; // count-down
}
m_work = false; // command thread to end
m_thread.join(); // wait for it to end
With output:
... 9_8_7_6_5_4_3_2_1_0_
work abandoned after 10,175,240 us
Overview: The method 'work' did not 'finish', but received the command to abandon operation and exit at timeout. (a successful test)
The code uses chrono and chrono_literals.
In windons OS
#include <windows.h>
Sleep( sometime_in_millisecs ); // note uppercase S
In Unix base OS
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
#include <unistd.h>
int usleep(useconds_t usec); // Note usleep - suspend execution for microsecond intervals
You want the sleep(unsigned int seconds) function from unistd.h. Call this function between the cout statements.

simultaneously run different thread without waiting for other thread to complete

The thing is i want to use c++ library which runs different threads simultaneously without having other threads to wait until the preceding thread is complete and their functionality within each thread is run simultaneuslly,I am talking about the code which is to be run in the thread;the sample code is shown below.
while(condition is true<it is infinite loop >){
running sleep here with random time
sleep(random time(sec))
rest of the code is here
}
This infinite while loop is run in each thread. I want to run this while loop in each thread to be run simultaneously without being stuck at the first thread to be completed. In other words all the infinite while loop(in each thread context) is to be run simultaneously. How do I achieve that? If you can please share some sample code actually I have used future with async but I get the same behavior as normal <thread> using join().
The issue you are encountering is because of the rather silly definition of std::async (in my opinion) that it doesn't have to execute your code asynchronously, but can instead run it when you attempt to get from its std::future return value.
No matter. If you set the first parameter of your call to std::launch::async you force it to run asynchronously. You can then save the future in a container, and if you retire futures from this container regularly, you can run as many threads as the system will let you.
Here's an example:
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <mutex>
using future_store = std::vector<std::future<void>>;
void retireCompletedThreads(future_store &threadList)
{
for (auto i = threadList.begin(); i != threadList.end(); /* ++i */)
{
if (i->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
i->get();
i = threadList.erase(i);
}
else
{
++i;
}
}
}
void waitForAllThreads(future_store &threadList)
{
for (auto& f : threadList)
{
f.get();
}
}
std::mutex coutMutex;
int main(int argc, char* argv[])
{
future_store threadList;
// No infinite loop here, but you can if you want.
// You do need to limit the number of threads you create in some way though,
// for example, only create new threads if threadList.size() < 20.
for (auto i = 0; i < 20; ++i)
{
auto f = std::async(std::launch::async,
[i]() {
{
std::lock_guard<std::mutex> l(coutMutex);
std::cout << "Thread " << i << " started" << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> l(coutMutex);
std::cout << "Thread " << i << " completed" << std::endl;
}
});
threadList.push_back(std::move(f));
// Existing threads need to be checked for completion every so often
retireCompletedThreads(threadList);
}
waitForAllThreads(threadList);
}