I have a function like this that is working fine:
void BigFunction()
{
void FunctionA(std::shared_ptr<ClassC> c);
}
now I want to add another function inside BigFunction()
void FunctionB(std::shared_ptr<ClassC> c);
which also take std::shared_ptr<ClassC> c as the input.
How do I do it correctly and safely so that both FunctionA() and FunctionB() can run in parallel, which means these two functions don't need to wait for each other and don't interfere with each other? Thanks.
Edit:
Here is the link of the code that I try but failed: https://onlinegdb.com/BJ5_BC0jI
You can use std::thread or std::future/std::async. For these "task"'s it is better/easier to use std::assync/future since the thread management is done for you.
bool func1(int a) {...}
bool func2(int a) {...}
void some_func()
{
std::future<bool> f1 = std::async(std::launch::async, func1, 1);
std::future<bool> f2 = std::async(std::launch::async, func1, 2);
bool res1 = f1.get(); // Only need this if you care about the result
bool res2 = f2.get(); // Only need this if you care about the result
}
If you don't care about the results you don't need that last two lines. But the .get() basically allows you to wait for your functions to finish. There are other options to do this... but its quite a general question...
Threads and lambda's:
bool func1(int a) {...}
bool func2(int a) {...}
void some_func()
{
std::thread t1 = []{ return func1(1); };
std::thread t2 = []{ return func2(2); };
// You must do this, otherwise your threads will go out of scope and std::terminate is called!
if (t1.joinable())
{
t1.join()
}
if (t2.joinable())
{
t2.join()
}
// Or instead of joining you can detach. But this is not recommend as you lose the ability to control your thread (left commented out as an example)
// t1.detach();
// t2.detach();
}
Update
Link to your "fixed" code: https://onlinegdb.com/S1hcwRAsL
Here is the code snippet for your convinience (and I am not sure if I have to save the changes! in GDB online!):
int main()
{
std::shared_ptr<classC> c = std::make_shared<classC>();
classB* b;
classA* a;
std::thread first([&b, &c]{ b->functionB(c); });
std::thread second([&a, &c]{ a->functionA(c); });
// synchronize threads:
first.join();
second.join();
std::cout << "A and B completed.\n";
return 0;
}
Related
My code:
void job_function(std::promise<void>& p) {
do_it();
p.set_value();
}
void foo() {
std::promise<void> p;
auto* thread = new std::thread(job_function, p);
p.get_future().wait_for(std::chrono::seconds(1));
}
In this code, if the calling thread of foo only waits for 1 second until the future completes. It is quite possible that the actual job gets completed after the wait is over. In this scenario, p is destructed already so call to p.set_value will not work. I can create p on heap, but even in that case it should be deleted and which thread should delete p depends on order of job completion and wait_for. Is there a specific pattern that can be used to handle this?
The trick is to move the promise into the thread and only keep the future around. Also, if you don't want to wait for the thread, detach it.
void job_function(std::promise<void> p) {
do_it();
p.set_value();
}
void foo() {
std::promise<void> p;
std::future<void> f = p.get_future();
std::thread thread(job_function, std::move(p));
thread.detach();
f.wait_for(std::chrono::seconds(1));
}
You are reimplementing std::packaged_task. Your code could be:
void job_function() {
do_it();
}
void foo() {
std::packaged_task<void(void)> task(job_function);
std::future result = task.get_future();
std::thread task_td(std::move(task));
result.wait_for(std::chrono::seconds(1));
}
shared_ptr to the rescue
void job_function(std::shared_ptr<std::promise> p) {
do_it();
p->set_value();
}
void foo() {
std::shared_ptr<std::promise> spPromise = std::make_shared<std::promise>();
auto* thread = new std::thread(job_function, spPromise);
spPromise->get_future().wait_for(std::chrono::seconds(1));
}
Now it doesn't matter if the thread completes before or after the original function that waits returns. The promise objects gets deleted when the last instance of the shared_ptr goes away.
If you want to keep the pass by reference semantics, just keep the shared_ptr captured by value for the lifetime of the thread.
void job_function(std::promise>& p) {
do_it();
p.set_value();
}
void foo() {
std::shared_ptr<std::promise> spPromise = std::make_shared<std::promise>();
std::promise& p = *spPromise.get();
auto* thread = new std::thread([spPromise] {
job_function(*spPromise.get()); // same as job_function(p)
});
p.get_future().wait_for(std::chrono::seconds(1));
}
I've read various answer on SO and still didn't understood how I should make an object method to be callable in this case:
Considering:
Class A
{
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
one(/***/);//Should be a flag
i = 2;
}
else
{
two(/**/);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
and a simple main file:
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
A myA;
A.One(pOne);
A.Two(pTwo);
int main(int argc, char** argv)
{
while(1){}
}
Here are where I'm at:
generator() should update a flag, and both one() & two() should poll on that flag & loop forever.
One() (two() also) should have a function pointer as parameters and if necessary other parameters, pOne() should have the same parameters except the function pointer.
So my questions are:
1) Is my understanding correct?
2) Is there a clean way to make generator() to start one() or two() ? (flags, semaphore, mutex, or anything that is a standard way to do it)
3) Assuming that the code was working, is it behaving as I expect ? i.e. printing 1 and 2?
if it matters, I'm on ubuntu
Disclaimer 1: Like everyone else, I'm interpreting the question as:
-> You need an event handler
-> You want callback methods on those events
And the only reason I think that is because I helped you on a i2c handler sequence before.
Also, there are better logic than this, its provided following your stubs "rules".
You mentioned that you are on Ubuntu, so you will be lacking windows event system.
Disclaimer 2:
1- To avoid going to deep I'm going to use a simple way to handle events.
2- Code is untested & provided for logic only
class Handler
{
private:
std::mutex event_one;
event_one.lock();
void stubEventGenerator(void)
{
for(;;)
{
if(!event_one.try_lock())
{
event_one.unlock();
}
sleep(15); //you had a sleep so I added one
}
}
template <typename CallbackFunction>
void One__(CallbackFunction && func)
{
while(1)
{
event_one.lock();
func();
}
}
public:
Handler()
{
std::thread H(&Handler::stubEventGenerator, this);
}
~Handler()
{
//clean threads, etc
//this should really have a quit handler
}
template <typename CallbackFunction>
void One(CallbackFunction && func) //I think you have it right, still I'm not 100% sure
{
std::thread One_thread(&Handler::One__, this, func); //same here
}
};
Some points:
One() as to be a wrapper for the thread calling One__() if you want it to be non-blocking.
mutex can be a simple way to handle events as long as the same event doesn't occur during its previous occurence (you are free to use a better/more suitable tool for your use case, or use boost:: only if necessary)
Prototype of One() & One__() are probably wrong, that's some research for you.
Finally: How it works:
std::mutex.lock() is blocking as long as it can't lock the mutex, thus One__ will wait as long as your event generator won't unlock it.
Once unlock One__ will execute your std::function & wait for the event (mutex) to be raised (unlock) again.
far from a perfect answer, but lack of time, and not being able to put that in a comment made me post it, will edit later
With whatever limited information you provided this code can be made compilable in following manner:
#include <iostream>
#include <thread>
typedef void(*fptr)();
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
class A
{
public:
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
fptr func = pOne;
one(func);//Should be a flag
i = 2;
}
else
{
fptr func = pTwo;
two(func);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
func();
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
func();
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
int main()
{
A myA;
while(1)
{
}
return 0;
}
If you want that one and two should accept any type/number of arguments then pass second argument as variadic template.Also I could not understand why you want one and two to be called from main as your generator function is for this purpose only and this generator function is called from thread which is detached in class constructor
So I have this function which is behaving like the setInterval function in JS. I found it here.
I am currently trying to change it so it can be stopped. I do not fully understand the behavior of this code.
void setInterval(function<void(void)> func, unsigned int interval) {
thread([func, interval]() {
while (1) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(interval);
func();
this_thread::sleep_until(x);
}
}).detach();
}
I tried it like this:
void setInterval(function<void(void)> func, unsigned int interval, bool &b) {
thread([func, interval, *b]() {
while (*b) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(interval);
func();
this_thread::sleep_until(x);
}
}).detach();
}
(this won't compile), and in main calling it like this:
bool B;
setInterval(myFunction,1000,B);
I was expecting that if I change the B variable to false, then the thread in setInterval function stops, but I haven't managed to reach my goal like this. Any idead/suggestions? Thank you in advance.
Sorry, but I didn't find a design simpler than that.
You could, make a class that owns both a thread, and a weak_ptr to itself,
to be a "holder" that the callable can see it safely, because the callable
will still exists even if the object is destructed. You don't want a dangling pointer.
template<typename T>
struct IntervalRepeater {
using CallableCopyable = T;
private:
weak_ptr<IntervalRepeater<CallableCopyable>> holder;
std::thread theThread;
IntervalRepeater(unsigned int interval,
CallableCopyable callable): callable(callable), interval(interval) {}
void thread() {
weak_ptr<IntervalRepeater<CallableCopyable>> holder = this->holder;
theThread = std::thread([holder](){
// Try to strongify the pointer, to make it survive this loop iteration,
// and ensure that this pointer is valid, if not valid, end the loop.
while (shared_ptr<IntervalRepeater<CallableCopyable>> ptr = holder.lock()) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(ptr->interval);
ptr->callable();
this_thread::sleep_until(x);
}
});
}
public:
const CallableCopyable callable;
const unsigned int interval;
static shared_ptr<IntervalRepeater<T>> createIntervalRepeater(unsigned int interval,
CallableCopyable callable) {
std::shared_ptr<IntervalRepeater<CallableCopyable>> ret =
shared_ptr<IntervalRepeater<CallableCopyable>>(
new IntervalRepeater<CallableCopyable>(interval, callable));
ret->holder = ret;
ret->thread();
return ret;
}
~IntervalRepeater() {
// Detach the thread before it is released.
theThread.detach();
}
};
void beginItWaitThenDestruct() {
auto repeater = IntervalRepeater<function<void()>>::createIntervalRepeater(
1000, [](){ cout << "A second\n"; });
std::this_thread::sleep_for(std::chrono::milliseconds(3700));
}
int main() {
beginItWaitThenDestruct();
// Wait for another 2.5 seconds, to test whether there is still an effect of the object
// or no.
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
return 0;
}
C++ is not JavaScript, but C++ can apply most programming paradigms in different languages.
In MyClass there are two functions. FuncA sends a command to be executed while FuncB checks the progress in executing the command sent by FunA. As FuncB waits in a while loop until it makes sure the command was successfully executed, I call FuncB in a separate thread. The thread in which FunA is running should not wait in a while loop.
In main.cpp, there are two functions which run in two different threads. execute makes decisions and call FunA to send commands while check calls FuncB to check the made decisions has been executed.
As I don't want execute to send the same decision more than once, I first make sure that FuncA is not running and that FuncB has reset funcInUse to false.
myclass.h
class MyClass
{
public:
MyClass();
void FuncA(float x, floaty, floatz);
bool FuncB(void);
bool IsFuncInUse(void);
void QuitFuncA(void);
private:
bool funcInUse;
bool _x;
std::mutex mtx;
}
myclass.cpp
MyClass::MyClass()
{
funcInUse = false;
}
void MyClass::FuncA(float x, float y, float z)
{
if(funcInUse == true)
{
printf("FuncA already in use\n");
return;
}
// Gaining the lock, so that no two threads call the function at the same time
mtx.lock();
funcInUse = true;
mtx.unlock();
printf("INSIDE FuncA()::: %d\n", funcInUse?1:0);
printf("THIS FuncA() adr=%p \n", this);
// DO STUFF
}
bool MyClass::FuncB(void)
{
if(funcInUse == true)
{
printf("THIS ISPOSREACHED() adr=%p \n", this);
// DO STUFF
// Giving the lock back before returning
mtx.lock();
funcInUse = false;
mtx.unlock();
printf("Function is no more in use\n");
}
return true;
}
bool MyClass:IsFuncInUse(void)
{
return isFuncInUse;
}
void MyClass:QuitFuncA(void)
{
mtx.lock();
funcInUse = false;
mtx.unlock();
}
main.cpp
MyClass myClass;
void timerStart(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
void execute(void)
{
if(/*some special condition*/)
{
myClass.QuitFuncA();
}
if(myClass.isFuncInUse() == false)
{
// USE THE FUNCTION
myClass.FuncA();
}
}
void check(void)
{
if(myClass.isFuncInUse())
{
status = myClass.FuncB();
printf("STATUS %d\n", status?true:false);
}
}
int main(void)
{
timerStart(execute, 500);
timerStart(check, 500);
}
The problem is: FuncA sets funcInUse to true in one iteration. In the next iteration, funcInUse is false again, although it was not been reset by FuncB. What may happen that resets funcInUse between the two iterations?
I tried printing this when calling the three functions in MyClass and all of them had the same address. I also tried to use bind with the class methods as I learned previously from here but it didn't work.
I tried to use mutex, semaphore and condition variables but I faced the problem that FuncA should gain the mutex while FuncB should release it after making sure the sent command has been executed (which is not allowed with mutex). And in one condition, a function in MyClass should reset isFuncInUse. Is there a better way to synchronize between the two methods than using funcInUse variable?
Thank you
I used to code on C++ long ago, but now decided to recall old skills and achieve some new ones :D
For now I am trying to rewrite my C# program in C++ and one problem occured - I don't know how to manage threads, or even how to create them, using class methods and calling methods from the class.
class MyObj {
private:
void thread() {
while (true) {
std::string a;
cin >> a;
}
}
static DWORD static_entry(LPVOID* param) {
MyObj *myObj = (MyObj*)param;
myObj->thread();
return 0;
}
public:
void start() {
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)static_entry, this, 0, NULL);
}
};
That is sample, I've found here, on StackOverflow but 'void thread()' was empty function, I've added code, given above, but the thread seems to start and close immediately.
I've added code, given above, but the thread seems to start and close immediately.
That's because you don't wait for threads to finish in your main thread.
As from their documentation, you'll need to add something like
// Wait until all threads have terminated.
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
For std::thread this should be a call to std::thread::join().
I'd rather recommend using std::thread as a member of the MyObj class:
class MyObj {
private:
void thread_fn() {
while (true) {
std::string a;
cin >> a;
}
}
std::thread t;
public:
void start() {
t = std::thread(&MyObj::thread_fn,*this);
}
~MyObj() {
if(t.joinable())
t.join();
}
};
Thank you for your answers.
Using std::thread turned out to be easier than using CLI Tread class.
static void input() {
while (true) {
std::string a;
cin >> a;
secureProg::execute_command(a);
}
}
auto start() {
std::thread thread(secureProg::input);
thread.join();
return thread.get_id();
}
Thread start from main
secureProg a;
auto thread_ptr = a.start();
Final version (I hope) of two methods within class