many to one conditional thread lock - c++

The problem:
First off, this is a simplified example of my problem, and it is really part of a large framework already programmed by someone else in which i have to adapt my code into.
I have 3 functions. Two of the functions (function1 and function2) are being called by other parts of the program both asynchronously and synchronously.
My last function (function3) runs continuously, like a while loop, and the only thing it does is to fire an event code on each code iteration.
I only want this last function to run whenever one of the two other functions have completed an iteration/been called.
I can not change how/when they are called, i can only block the execution of the code and unblock it.
I am fairly new to c++ and i have tried solving this using a mutex, but i have had no luck.
I can add the code, but it really is just like i explained.
void function1(){ // this function is called by other parts of the program
//some code
}
void funtion2(){ //this function is also called by other parts of the program
//some other code
}
void function3(){ //this function runs continuously, similar to a while loop with a 1ms sleep in it
fireEvent();//fires an event to run some other code
}
So, function3 runs all the time unless blocked, and i would only like to run the function every time one of the other functions have had one run-through. Like i said before, i can not call function3 myself, i can only manipulate the code in the function.
What is the best way of going about this?
After intense googleing i have only come up with conditional variables, semaphore and mutex, but i don't know enough about them to know how i can implement it correctly.
Any help/input/tip is greatly appreciated.

A straigtforward way would be like this:
mutex g_mutex;
condition_variable g_cond;
bool flag = false;
void function1(){ // this function is called by other parts of the program
//some code
lock_guard<mutex> lock(g_mutex);
flag = true;
g_cond.notify_one();
}
void funtion2(){ //this function is also called by other parts of the program
//some other code
lock_guard<mutex> lock(g_mutex);
flag = true;
g_cond.notify_one();
}
void function3(){ //this function runs continuously, similar to a while loop with a 1ms sleep in it
{
unique_lock<mutex> lock(g_mutex);
g_cond.wait(lock, []{return flag;}); // wait here until func1 or func2 have been called
flag = false;
}
fireEvent();//fires an event to run some other code
}
int main() {
// your code goes here
return 0;
}
But this will block your function3 until one of the other twos are called. So it is a change of the behaviour and it adds additional lock contention.

Related

Is this threadpool usage safe?

I'm posting several jobs to a threadpool and then waiting for it to finish. I'm wondering if I've missed something here, since occasionally my worker threads seem to freeze.
My main thread start the workers like this:
numJobsPosted = 0;
for(auto entry : list)
{
numJobsPosted++;
threadPool->post(std::bind(&Controller::workerFunc, this, entry));
}
std::unique_lock<std::mutex> lock(m_workerLock);
while(numJobsPosted > 0)
{
m_workerCondition.wait(lock);
}
Now my workerFunc looks something like this:
void Controller::workerFunc(Entry entry)
{
// do some work with entry
// notify finished
numJobsPosted--;
if(numJobsPosted <= 0)
{
// does the look need to be around the numJobsPosted-- ?
std::unique_lock<std::mutex> locker(m_workerLock);
m_workerCondition.notify_one();
}
}
Is the above code safe, or do I need to put the lock around the decrement operator?
This may depend on details of your thread pool's inner logic or setup (e.g. if you have a single thread, so jobs are actually run sequentially), but assuming that numJobsPosted is an int or similar built-in type, your code isn't thread-safe.
This line in workerFunc:
numJobsPosted--;
could very well be the subject of a race condition if it gets executed by several jobs concurrently.
Also, I'm not sure what your threadpool's post function does precisely, but if it dispatches the worker function to a thread right away and some of the worker functions can return immediately, you have another possible race condition between this line in your main thread code:
numJobsPosted++;
and this line in workerFunc:
numJobsPosted--;
To make it safe, you can for instance make numJobsPosted atomic, e.g. declare it like this (in C++11):
#include <atomic>
std::atomic_int numJobsPosted;
Making your workerFunc something like this:
void Controller::workerFunc(Entry entry)
{
// do some work with entry
// notify finished
{
std::unique_lock<std::mutex> locker(m_workerLock);
numJobsPosted--;
if(numJobsPosted <= 0)
{
m_workerCondition.notify_one();
}
}
}
may solve the first race condition case, but not the second.
(Also, I don't really understand the logic around the manipulation and testing you're doing on numJobsPosted, but I think that's beside the point of your question)

Make something happen after 5 minutes has passed, while other code still runs in C++

I am trying to make a timer, so after five minutes something happens. The catch is that while the timer is being checked constantly I need other code to be running. I have created a sample below, of how the actually code looks, the function with the timer is in class, so I did the same thing below. Here is the code:
This code assumes all necessary headers are included
Class.h:
class MyClass
{
public:
void TimerFunc(int MSeconds);
};
void MyClass::TimerFunc(int MSeconds)
{
Sleep(MSeconds); //Windows.h
//Event code
return;
}
Main.cpp:
int main()
{
MyClass myClass;
myClass.TimerFunc(300); //300 is 5 minutes
//Here we do not want to wait for the five minutes to pass,
//instead we want to continue the rest of the code and check
//for user input as below
std::cout << "This should print before the Event Code happens.";
}
The problem here is that the code waits for the five minutes to pass, and then continues. I'm not sure if threading would be a good option here, I haven't done much with it before, if anyone could help me with that, or knows a better way to go about it, any help is appreciated.
If you don't mind your Event executing in a different thread-context, you could have your Timer class spawn a thread to do the waiting and then the event-execution; or (on POSIX OS's) set up a SIGALRM signal and have the signal handler do the Event. The downside of that is that if your event-code does anything non-trivial, you'll need to worry about race conditions with the concurrently executing main thread.
The other approach is to have your main thread check the clock every so often, and if the time-to-execute has passed, have your main thread call your Event routine at that time. That has the advantage of automatic thread-safety, but the disadvantage is that you'll have to add that code into your thread's main event loop; you can't easily hide it away inside a class like the one in your example.
With C++11 threads, this would work like this:
int main()
{
MyClass myClass;
thread ti([](MyClass &m){m.TimerFunc(300); }, ref(myClass)); // create and launch thread
// ... code executed concurrently to threaded code
ti.join(); // wait for the thread to end (or you'll crash !!)
}
Add a private member to your class:
atomic<bool> run=true; // designed to avoid race issue with concurrent access
Update its timer function to loop while this variable is true:
void MyClass::TimerFunc(int MSeconds)
{
while (run) {
this_thread::sleep_for(chrono::milliseconds(MSeconds)); // standard sleep instead of microsoft's one
//Event code
}
return;
}
Foresee within the class a member function to stop the threaded loop:
void Stop() {
run = false;
}
Finally update main() to call myClass.Stop() when the timer function is no longer needed (i.e. before calling ti.join() )
EDIT: attention, nasty error to avoid: be careful to refer to ref(myClass) in the thread constructor. If you would forget this, the thread ti would use a reference to a copy of myClass instead of the original object.

Thread is not working properly

I have a class Machine with some member function. In the makeProduct I make a thread that calls t_make and then returns. While the thread is doing it's work in the member function I still want to use Machine(status check, resource left, etc.)
I started like this
//machine.h
private
int stat;
std::thread t;
std::mutex m;
bool working;
//machine.cpp
int Machine::makeProduct(){
if(working == true) return -1;
t = std::thread(&Machine::t_make, this);
return 0;
}
void Machine::t_make(){
std::lock_guard<std::mutex> guard(m);
//do some time-consuming work, change "stat" in progress
}
void Machine::Status(int &copStat){
copStat = stat;
}
Machine::~Machine(){ if(t.joinable()) t.join; }
//main.cpp
...
Machine m;
m.makeProduct();
int getStat = 0;
m.Status(getStat);
if(getStat == 1) cout<< "Product in making";
...
The problem is that when I call makeProduct() and right after that Status() the copStat doesn't change, indicate that any work was done.
Am I using the t or t_make wrong? I tried posting lock_guard in every method but the threads don't intertwine. Or maybe the t.join() at the wrong time, but let me just mention that if I place 't.join' right after using t = std::thread(&Machine::t_make, this); and everything work out fine.
When you call Status() right after you call getProduct(), there's a good chance that the new thread hasn't started doing anything yet. You are still in the original thread, and the new thread has to set up and start running.
Your join in the destructor is not really meaningful for this exercise. If you wanted to make sure to collect the result and do something with it as Machine goes out of scope it may make sense, but it isn't meaningful to your question about checking Status. If you want Status() to only return you the value after t_make() is finished, then moving your join() code to Status would work.
Look at the Futures in the standing threading library http://en.cppreference.com/w/cpp/thread#Futures. These are utilities for executing asynchronous tasks and getting the result when the task is complete.
If t_make is modifying 'stat', then your Status function should acquire the lock before using 'stat' in the assignment of the copStat. The memory access is currently unsafe.
As the code stand right now, if you're expecting the t_make call to be complete before calling Status, there is nothing forcing this to happen. As is, two separate threads will be autonomously completing these actions - 1 thread calling t_make and 1 thread calling Status. There is no guarantee as to what order this happens in. (this changes if you add a lock to Status)
Also, could you update your example to show how you're determing that copStat is never populated?

How can I cancel a std::async function? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a way to cancel/detach a future in C++11?
There is a member function which runs asynchronously using std::future and std::async. In some case, I need to cancel it. (The function loads near objects consecutively and sometimes an objects gets out of range while loading it.) I already read the answers to this question addressing the same issue, but I cannot get it work.
This is simplified code with the same structure as my actual program has. Calling Start() and Kill() while the asynchronous is running, causes a crash because of access violation for input.
In my eyes the code should work as follows. When Kill() is called, the running flag is disabled. The next command get() should wait for thread to end, which it does soon since it checks the running flag. After the thread is canceled, the input pointer is deleted.
#include <vector>
#include <future>
using namespace std;
class Class
{
future<void> task;
bool running;
int *input;
vector<int> output;
void Function()
{
for(int i = 0; i < *input; ++i)
{
if(!running) return;
output.push_back(i);
}
}
void Start()
{
input = new int(42534);
running = true;
task = async(launch::async, &Class::Function, this);
}
void Kill()
{
running = false;
task.get();
delete input;
}
};
It seems like the thread doesn't notice toggling the running flag to false. What is my mistake?
Since noone's actually answered the question yet I'll do so.
The writes and reads to the running variable are not atomic operations, so there is nothing in the code that causes any synchronisation between the two threads, so nothing ever ensures that the async thread sees that the variable has changed.
One possible way that can happen is that the compiler analyzes the code of Function, determines that there are never any writes to the variable in that thread, and as it's not an atomic object writes by other threads are not required to be visible, so it's entirely legal to rearrange the code to this:
void Function()
{
if(!running) return;
for(int i = 0; i < *input; ++i)
{
output.push_back(i);
}
}
Obviously in this code if running changes after the function has started it won't cause the loop to stop.
There are two ways the C++ standard allows you to synchronize the two threads, which is either to use a mutex and only read or write the running variable while the mutex is locked, or to make the variable an atomic variable. In your case, changing running from bool to atomic<bool> will ensure that writes to the variable are synchronized with reads from it, and the async thread will terminate.

Start new thread without blocking/waiting of main operation

Maybe there is a really simple solution for my problem, but I'm really confused with all the boosts around me.
Here's my problem:
I want to start a task (calculation, file system operations, etc.), raised by a callback system which calls the CallbackReceived function and I want to pass this operation to a thread, typically represented by a member function of an object. The thread isn't guaranteed to finish, so it should have something to cancel it after some time.
Something like (don't know if this is 100% correct):
// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
boost::thread tThread(&MyObject::calculate, *&object);
boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2));
tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));
tThread.join();
}
Basically, a tThread.join()` waits for the return of the thread. While waiting, my main could not receive any callbacks that may come in because it's blocked and sleeps.
So what can one do, to run the thread and not to block the calling initial program while executing the operation?
You can call join just when you need the result of the calculations.
Something like "Future" pattern. Anyway, you would have to make your thread variable global to the CallBackRecieved function (You can write some wrapper).
Note: you can call join, when thread finished its' work - nothing will be blocked.
What do you want to do with the result of calculate?
Your main thread is blocked in the .join().
If you want to handle other callbacks, you have to return to the normal execution flow, waiting for another call.
Then you have to ask yourself what do you do with the result of calculate when it's finished. Maybe the thread can put the result in a shared resource somewhere and finish gracefully.
You must first sort out all what your code is supposed to do ( processing callbacks, starting threads, what to do with the result ) then you can think of implementing it. There are new constructs in boost and C++11 called promise and future that could suit you but first you have to think about what you want.
Actually you could call the callback while your main thread is sleeping. It would just run on the context (stack) of your thread.
You probably don't want to call join at the point you are at but later or never.
Example (pseudocode):
class Worker {
void doWork(void * mainthread){
Main* main = static_cast<Main*>(mainthread);
while(hasWorkTodo){
//work
//inform main
main->callbackwithinformation(information);
}
}
class Main{
atomi_int filesfound;
void main_part(){
//start worker
boost::thread thread(&Worker::doWork, &object, this);
while(hasworktodo){
//do work
//use filesfound here
}
//About to finish make sure we join our thread
thread.join();
}
void callbackwithinformation(int updatedcount){
//here we set a flag or pass some object
//probably will need an atomic operation
filesfound = updatedcount;
}
}
You would define the implementations in cpp and the interface in a h file so no circular dependency would arise, since you are only using Main as a argument in the interface a forward declaration would suffice.
//worker.h
class mainthread;
class Worker {
void doWork(void * mainthread);
}
//worker.cpp
#include "main.h"
void Worker::doWork(/* and so on*/}
//main.h
class Main{
atomi_int filesfound;
void main_part();
void callbackwithinformation(int updatedcount);
}
//main.cpp
//no need for worker.h here
void Main::main_part() /* implementation and so on */